• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

wc -w funktioniert plötzlich nicht mehr mit backticks

In einem Skript werden die file-Namen in einem Verzeichnis mit

FILES=`ls -l *.xmlmod`

in einen Textstring geladen.
Anschließend wird die Anzahl dieser Filenamen mit

FILECNT=`echo $FILES | wc -w`

ermittelt . Das ist nicht unbedingt so, wie man es optimal macht - ich hab's nicht selber geschrieben, hat aber 12 Jahre funktioniert. Seit letzter Woche funktioniert das auf dem Server, auf dem es 12 Jahre gelaufen ist, nicht mehr, die FILECNT.Zuweisung liefert offenbar nichts zurück, also auch nicht 0, obwohl der String FILES gefüllt ist. Man merkt es daran, dass die Abfrage

if [ $COUNTER != $FILECNT ]...

auf einen Syntaxfehler läuft, weil in $FILECNT nichts drin steht.
Interessanterweise tritt der Fehler nur auf einem bestimmten Server auf, auf allen anderen Servern funktioniert das nach wie vor. Angeblich ist auf diesem Server nichts anders - es fällt nur der Zeitpunkt, ab dem der Fehelr auftritt, mit der Installation einer neuen sentinelone-Version zusammen.
Die LC_ALL, LC_LANG,...-Parameter habe ich geprüft, die haben offenbar keinen Einfluss auf wc und/oder die backticks.

Hat jemand eine Idee, wo man da nachgucken könnte?
(Das Skript kann man natürlich anpassen, dass es ohne die umständliche Abfrage läuft, aber damit kennt man ja noch nicht die Ursache...)
 
Wäre es ein Debiansystem würde ich als erstes prüfen ob die Shell immer noch die ist die Du erwartest. Oder halt im Skript explizit die gewünschte Shell aufrufen und nicht mit "#!/bin/sh" arbeiten. Nur mal so als Schuß ins Blaue
 
Ja, danke, da habe ich auch schon dran gedacht, aber daran hat sich ja nichts geändert nachdem es 12 Jahre gelaufen ist.
Es ist eine GNU bash, Version 4.4.12(3)-release (i686-pc-cygwin).
Das Problem ist, dass da nur im Prod-Umfeld der Fehler auftritt und ich da nicht ohne weiteres testen kann, weil da zu viel dran hängt. In den Testenvironments funktioniert es nach wie vor, deswegen wäre es gut, das Problem "trocken" zu finden. Natürlich wird das Skript geändert - mit irrem Testaufwand - aber es kann ja sein, dass sich das Problem auch in anderen Skripten auswirkt, wo es noch nicht aufgefallen ist oder noch nicht gelaufen ist und wo es dann nicht behoben ist. Deswegen wäre es gut, die Ursache zu finden und möglichst zu behebn.
 

framp

Moderator
Teammitglied
Code:
FILES=`ls -l *.xmlmod`
finde ich etwas ungeschickt und ich hätte eher
Code:
FILES=`ls -1 *.xmlmod`
genommen denn der FILECOUNT ist dann auch wirklich die Anzahl der Dateien und muss nicht erst durch 9 geteilt werden.

Davon abgesehen: Ich denke nicht dass sich das Verhalten der Backticks geändert hat. Ich vermute das Ergebnis von ls -l *.xmlmod sieht unterschiedlich aus. Du hast ja ein System wo es funktioniert. Vergleiche doch mal hexadecimal die Ergebnisse.
 
Zuletzt bearbeitet:
Schönen Dank für die Analyse, aber das ist nicht das Problem. Dass man das anders und besser machen ist klar das wird auch passieren, ich habe das ja auch schon oben beschrieben. Das Problem ist, warum liefert

FILECNT=`echo $FILES | wc -w`

bei nachweislich gefülltem Strimg $FILES (die Dateien, die da drin stehen, werden verarbeitet) ein Blank zurück, wo doch "wc -w" eine Zahl, ungünstigstenfalls eine 0, liefern müsste - und warum tut es das auf einem Server plötzlich falsch und auf dem anderen Server nach wie vor korrekt. Ich kann es wie gesagt auf dem Produktionsserver nicht testen und auch keinen Hexwert oder sonst was abfragen. Das würde auch nichts nützen, weil das Problem damit ja noch nicht lokalisiert wäre.
Es wäre hilfreich, wenn ich es zumindest auf dem Testserver nachvollziehen könnte, aber da ist eben die Frage, an welchem environment-Parameter (o.ä.) muss ich drehen, damit das passiert. Die Systemadministration behauptet, es wäre nichts geändert, aber das kann nicht stimmen. Zumindest ist eine neue sentinelone-Version eingespielt worden und meine Vermutung war, dass der LANG-Parameter anders gesetzt wurde ( auf C ) und dann eventuell der Wortbegrenzer anders interpretiert wird - aber das habe ich im Test ausprobiert, die Abfrage funktioniert da trotzdem korrekt.
 
1. Bist Du sicher, daß in $COUNTER und $FILECNT Werte vorhanden sind?

2. Ich glaube nicht, daß Du dieses Problem in der Theorie lösen kannst. Du wirst auf dem betroffenen Server (oder einer 1:1-Kopie davon) Analyse-Skripte ausführen (lassen) müssen.
 
P.S. Warum muss der FILECNT durch 9 geteilt werden? Da stand bisher und steht auch im Test nach wie vor exakt die Anzahl der Files - also bei dem String FILES die Anzahl der durch Whitespace separierten Teilstrings - drin?
(Ich will diese Konstruktion nicht verteidigen, mir gefällt das aus verschiedenen Gründen auch nicht, aber das ist seit 13 Jahren zigtausendmal gelaufen...).
Der Hintergrund der Abfrage ist, dass die Dateien in FILES vearbeitet werden, nur bei der letzten, die am FILECNT erkannt wird, passiert etwas nicht. Und diese Abfrage funktioniert nicht, wenn in FILECNT kein numerischer Wert steht.
 
Zu 1: In $COUNTER iste ein Wert vorhanden, in $FILECNT eben nicht, dass ist ja das Problem auf diesem Server - im Test schon.
zu 2: Der Prod-Server ist angeblich laut Administrator eine exakte Kopie des Servers auf dem getestet wird. Es ist halt nur so, dass dasselbe Skript sich unterschiedlich verhält...
 
Nach Allem was Du beschreibst, schreit es für mich nach "andere shell". Wäre etwas wie coreutils deinstalliert worden, würde das Skript gar nicht mehr laufen. Ganz im Zweifel könntest Du versuchen statt der backticks das Konstrukt $() zu verwenden.
 
Danke für die Antwort, aber das anders zu machen ist nicht das Problem,s.o.
Dass eine andere shell gerufen wird, ist laut Administration und dem was ich sehe, nicht der Fall, und selbst wenn - wo ist der Unterschied? Die Ursache zu finden halte ich für angebracht, weil die Auswirkungen eventuell noch auf andere Skripte, in denen ähnlich veralteter Code läuft - bis jetzt....
 

susejunky

Moderator
Teammitglied
Ich habe hier ein Verzeichnis mit 4 PDF-Dateien
Code:
> ls -l
insgesamt 340
-rw------- 1 user1 user1 88227  1. Sep 2017  Google_Play_Geschenkkarte_Geschenkcode_Gutscheincode_einlösen.pdf
-rw------- 1 user1 user1 78202  1. Sep 2017  Google_Play-Guthaben_erhöhen_abfragen.pdf
-rw------- 1 user1 user1 91568  1. Sep 2017  Google_Play_Nutzungsbedingungen_Geschenkkarten.pdf
-rw------- 1 user1 user1 80870  1. Sep 2017  Google_Play_Verwendungsmöglichkeiten_Guthaben.pdf
>

Ich verwende
Code:
> bash --version
GNU bash, Version 5.2.37(1)-release (x86_64-suse-linux)
Copyright (C) 2022 Free Software Foundation, Inc.
Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>

Dies ist freie Software. Sie darf verändert und verteilt werden.
Es wird keine Garantie gewährt, soweit das Gesetz es zulässt.
>
und
Code:
> wc --version
wc (GNU coreutils) 9.7
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Paul Rubin and David MacKenzie.
>

Ich sehe folgende Ergebnisse:
Code:
> ANZ=4 ; FILES=`ls -l *.pdf`; FILECNT=`echo $FILES | wc -w`; if [ $ANZ != $FILECNT ]; then echo $FILECNT; else echo "OK"; fi
36
>
Code:
> ANZ=4 ; FILES=`ls -1 *.pdf`; FILECNT=`echo $FILES | wc -w`; if [ $ANZ != $FILECNT ]; then echo $FILECNT; else echo "OK"; fi
OK
>
(mit der -1 an Stelle des -l bei wc)

Meines Erachtens kann man nur dann eine absolut fehlerfreien Funktion erwarten, wenn die eingesetzten Softwareversionen auf Test- und Produktionssystem 100% übereinstimmen. Abweichende Versionsstände können funktionieren, müssen aber nicht.
 
Dass eine andere shell gerufen wird, ist laut Administration und dem was ich sehe, nicht der Fall, und selbst wenn - wo ist der Unterschied?
Ich habe es erst vor nicht allzulanger Zeit selbst gehabt das eine Software, die Skripte nutzte, bei mir nicht laufen wollte, obwohl nach meinem Empfinden in dem Skript Alles in Ordnung war. ABER das Skript wurde im Systemuserkontext aufgerufen, also eine UID unter 1000. Das bedeutet das bei Debian dafür dash verwendet wird und nicht bash was ich sonst für alle User benutze. Und bei dash sind einige Konstrukte anders als bei bash. Kaum den She-Bang geändert auf "/usr/bin/bash" schon lief es wie es sollte.
 

susejunky

Moderator
Teammitglied
Wenn die Dateinamen Leerzeichen enthalten
Code:
> ls -l
insgesamt 340
-rw------- 1 b1 b1 88227  1. Sep 2017  Google Play Geschenkkarte Geschenkcode Gutscheincode einlösen.pdf
-rw------- 1 b1 b1 78202  1. Sep 2017  Google Play Guthaben erhöhen abfragen.pdf
-rw------- 1 b1 b1 91568  1. Sep 2017  Google Play Nutzungsbedingungen Geschenkkarten.pdf
-rw------- 1 b1 b1 80870  1. Sep 2017  Google Play Verwendungsmöglichkeiten Guthaben.pdf
>
wird es noch schlimmer
Code:
> ANZ=4 ; FILES=`ls -l *.pdf`; FILECNT=`echo $FILES | wc -w`; if [ $ANZ != $FILECNT ]; then echo $FILECNT; else echo "OK"; fi
51
>
aber auch mit ls -1 funktioniert es dann nicht mehr
Code:
> ANZ=4 ; FILES=`ls -1 *.pdf`; FILECNT=`echo $FILES | wc -w`; if [ $ANZ != $FILECNT ]; then echo $FILECNT; else echo "OK"; fi
19
>
Aber
Code:
> ANZ=4 ; FILECNT=`ls -1 | wc -l`; if [ $ANZ != $FILECNT ]; then echo $FILECNT; else echo "OK"; fi
OK
>
würde auch bei Dateinamen, die Leerzeichen enthalten funktionieren.

Allerdings erklärt das alles nicht, warum das Skript auf Deinem Produktionssystem in FILECNT
bei nachweislich gefülltem Strimg $FILES (die Dateien, die da drin stehen, werden verarbeitet) ein Blank zurück [gibt], wo doch "wc -w" eine Zahl, ungünstigstenfalls eine 0, liefern müsste
 
Na ja, vielen Dank für die Mühe, so ungefähr sieht das bei mir auch aus, wenn ich das teste.
Aber das ist ja gerade mein Problem: Die Admin behauptet, die Stände sind gleich, es ist nichts geändert worden. Trotzdem funktioniert die Abfrage nicht.

Im SYSOUT, wo der $FILECOUNT zur Kontrolle ausgegeben wird, steht in Prod nichts (Im Test, wo es funktioniert, sieht man da die Anzahl...)
Den Effekt, der auftritt, kann ich in der Entwicklungsumgebung nur erzielen, wenn ich hart in den $FILECOUNT ein Blank setzte. dann führt die if-Abfrage
im SYSOUT zu der Meldung

"Einstelliger (unärer) Operator erwartet"

und wird nicht ausgeführt - das ist das, was auf dem Prod-Server auch passiert und weil dss Skript nicht abbricht zu fehlerhafter Verarbeitung führt.

Daraus schließe ich, dass

FILECNT=`echo $FILES | wc -w`

ein Blank liefert und der Interpreter anschließend die Test-Abfrage nicht syntaxgemäß aufbaut.

Die Frage ist also, was in irgendwelchen Einstellungen beeinflusst den wc und/oder den Gravis-Einsatz so, dass da nach 13 Jahren plötzlich etwas anderes bzw. nichts geliefert wird. Möglich wäre z.B. dass die shell den backtick nicht mehr erkennt und die Zuweisung dann ins Leere läuft - ist ja nach dem , was man so liest eh veraltet - aber das müsste doch dann irgendwo erkennbar sein.

Wenn da keiner eine Idee hat, kann man das nicht ändern, falls eine Erklärung gefunden wird, werde ich das hier vermerken.
 
Ja, dem Hinweis von Geier0815 mit dem unterschiedlichen Usern werde ich nochmal nachgehen, allerdings liefert die Abfrage mit "which" für "wc" eindeutig /usr/bin. Das müsste dann nochmal der root machen, mal gucken, ob da etwas anderes kommt - das müsste ja dann aber auch im $PATH erkennbar sein. Dazu würde ggf. passen, dass in dem alten Skript keine !/bin/bash Angabe vorhanden ist.
Mal sehen...
 

susejunky

Moderator
Teammitglied
wo der $FILECOUNT zur Kontrolle ausgegeben wird

FILECNT=`echo $FILES | wc -w`

ermittelt . Das ist nicht unbedingt so, wie man es optimal macht - ich hab's nicht selber geschrieben, hat aber 12 Jahre funktioniert. Seit letzter Woche funktioniert das auf dem Server, auf dem es 12 Jahre gelaufen ist, nicht mehr, die FILECNT.Zuweisung liefert offenbar nichts zurück, also auch nicht 0, obwohl der String FILES gefüllt ist. Man merkt es daran, dass die Abfrage

if [ $COUNTER != $FILECNT ]...
Was denn nun, FILECOUNT oder FILECNT?

Daraus schließe ich, dass
Deine Vermutungen mögen zutreffen, aber exakte Angaben aus dem Produktionssystem wären für eine Problemanalyse hilfreicher.

Der Hintergrund der Abfrage ist, dass die Dateien in FILES vearbeitet werden, nur bei der letzten, die am FILECNT erkannt wird, passiert etwas nicht. Und diese Abfrage funktioniert nicht, wenn in FILECNT kein numerischer Wert steht.
Dazu ist aber mehr oder eine andere Programmlogik erforderlich als
if [ $COUNTER != $FILECNT ]...
 
Na ja, das ist ein Tippfehler von mir und das ganze Skript wollte ich hier nicht diskutieren. Es ging mir nur darum, zu fragen, ob jemand weiß oder schon mal gehört hat, was eventuell das Verhalten von "wc" oder den Gravis in den Environment-Einstellungen oder sonstwo schlagartig von einem Tag auf den anderen beeinflussen kann bei angeblich keiner Änderung seitens der Systemadministration.
Aber das schaffe ich anscheinend nicht - so ein Skript anpassen kann ich schon selber.
 
Oben