• 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

framp

Moderator
Teammitglied
P.S. Warum muss der FILECNT durch 9 geteilt werden?
Weil ls -l folgene Informationen für eine Datei anzeigt:
Code:
-rw-rw-r-- 1 framp framp   4950 May 21 13:27 Makefile
und das sind 9 durch Leerzeichen getrennte Worte die mit wc -w gezählt werden. Siehe auch die Beispiele von @susejunky : Er hat 4 Dateien und der Count 36 wird zurückgeliefert.

Wenn Dir in Deinem Code aber wirklich die korrekte Anzahl Dateien geliefert wird - was passiert wenn Du ls -1 nimmst, kann ich daraus nur vermuten dass das Ausgabeformat von ls -l durch irgendeine Einstellung nur den Dateinamen zurückliefert. Der Einwand von @susejunky zu Dateinamen mit Leerzeichen ist natürlich auch zu berücksictigen.

Die Backticks funktionieren zu 100%. Ansonsten würde sich wohl auf dem System kein Rad mehr drehen.

Ich sehe es so wie @josef-wien in Punkt 2. Du musst auf dem Produktionssystem debuggen. Alles andere ist Satzleserei und Du wirst kaum Erfolg haben. Ist es denn wirklich nicht möglich ein einfaches xxd <<< "$FILES" >> /var/log/debugMe an der entsprechenden Stelle einzubauen? Dadurch wird defintiv die Funktionalität des Codes nicht geändert.
 
Ja, danke, der ls ist "ls -1..." und das funktioniert alles, die $FILES sind auch nicht das Problem, das funktioniert - leider - alles, auch auf dem Server wo der Fehler mit "FILECNT=`echo $FILES | wc -w* auftritt und in dem FILECNT steht defintiv nichts drin, da nützt mir auch kein Hexaldump.
Nein, da wo der Fehler auftritt kann ich nicht so ohne weiteres Testen, das Skript muss funktionsfähig aus Annahme nach Produktion gehen, weil das Skript Ausgaben erzeugt, die sofort zum externen Provider gehen und das zu unterdrücken ist ein ziemlicher Aufwand.
Ich werde das schon irgendwie lösen, das Skript ohne diesen merkwürdigen Count zu erstellen ist nicht das Problem, das mache ich alle Tage.
Nur - ich wiederhole mich - eigentlich läuft das seit ca. 13 Jahren und wenn da irgendetwas plötzlich anders funktioniert, hat das vielleicht Auswirkungen auch auf andere Skripte, deswegen würde ich die Ursache gern kennen.
 

susejunky

Moderator
Teammitglied
eigentlich läuft das seit ca. 13 Jahren und wenn da irgendetwas plötzlich anders funktioniert, hat das vielleicht Auswirkungen auch auf andere Skripte, deswegen würde ich die Ursache gern kennen.
In den vorangegangenen Beiträgen wurden Dir doch die zwei Bereiche aufgezeigt, welche die Problemursache beherbergen könnten:
  1. Änderungen in den eingesetzten Softwareversionen und/oder Abweichungen in den Softwareständen zwischen Produktiv- und Testsystem.
  2. Mängel im Skript (siehe Beitrag #16).
zu 1.)
Ohne konkrete Informationen über die eingesetzten Softwarestände und ggf. den Aktualisierungsverlauf kann man Dir diesbezüglich nicht weiter helfen (und Du bist ohnehin der Ansicht, dass das nicht die Ursache des Problems sein kann).

zu 2.)
Das Beispiel in Beitrag #16 zeigt, dass das Skript (soweit Du es hier zugänglich gemacht hast) an Dateinamen, welche Leerzeichen enthalten, scheitern würde. Dass dieser Sachverhalt bislang (13 Jahre ?) unentdeckt geblieben ist, könnte sich dadurch erklären lassen, dass die Testdaten, die Du auf Deinem Testsystem verwendest, keine Dateinamen mit Leerzeichen beinhalten.

Ich will damit nicht sagen, dass Dateinamen mit Leerzeichen die Ursache für das aktuelle Versagen des Skripts darstellen. Aber ich halte es durchaus für möglich, dass das Skript noch weitere implizite Annahmen (wie z.B. Dateinamen beinhalten keine Leerzeichen) bezüglich der zu verarbeitenden Daten trifft und dass diese Annahmen nach 13 Jahren nicht mehr zutreffen, was dann zu einem Scheitern des Skripts führt. Dass das Skript bis vor kurzem sowohl auf dem Produktiv- als auch auf dem Testsystem problemlos lief, kann daher kommen, dass die verwendeten Testdaten eben nicht alle Fälle der aktuell im Wirkbetrieb anfallenden Daten abdecken.

Um es etwas verständlicher zu machen hier ein kleines Beispiel "aus meinem Nähkästchen":

Bei einem Kunden war seit Anfang 1990 ein System in Betrieb (klaglos), welches Mitte Januar 2000 plötzlich Probleme verursachte. Die Analyse ergab, dass an einer Stelle im Programm eine 10-stellige Kundennummer auf Gültigkeit geprüft werden sollte und die Prüfung bestand in der Auswertung der letzten beiden Ziffern der Kundennummer, welche das Jahr, in dem der Kunde zum Kunden geworden war, abbildeten. Da das Unternehmen seit 1985 tätig war, sollte die Gültigkeit einer Kundennummer dadurch festgestellt werden, dass die letzten beiden Ziffern einen Wert >=85 ergaben (wurde vom Kunden so spezifiziert und vom Softwareersteller gemäß Spezifikation realisiert). Das funktionierte 10 Jahre wunderbar bis dann der erste neue Kunde im Januar 2000 erfasst wurde.

Um solche Fälle oder eben den in Beitrag #16 beschriebene zu erkennen, muss
  • bekannt sein, welche Funktionalität durch den Programmcode abgedeckt werden soll (Spezifikation),
  • der Programmcode analysiert; d.h. mit der Spezifikation abgeglichen werden und dann
  • unter Verwendung von Testdaten, die möglichst alle je im Wirkbetrieb zu erwartenden Datenkonstellationen abdecken, überprüft werden.
Das Alles ist Dir sicherlich bereits bekannt, da das Erstellen komplexer Skripte Dein "täglich Brot" ist. Du musst es jetzt eben nur noch umsetzen. Ich denke viele Forumsmitglieder (mich eingeschlossen) würden Dich dabei gerne unterstützen. Aber ohne das Skript vollständig zu kennen und ohne zu wissen, was das Skript leisten soll (Spezifikation) ist das kaum möglich.
 
Vielen Dank für die ausführliche Antwort, aber alles was mir als Anwendungsentwickler zugänglich ist, funktioniert ja, das ist das Problem!
Es ist derselbe Code, der auf dem einen Environment (MMWBATCH02), auf dem er 13 Jahre fehlerfrei gelaufen ist, jetzt fehlerhaft läuft, in Produktion auf einer andere Maschine ( MMWBATCH01) als Verlegenheitslösung jetzt provisorisch fehlerfrei in Betrieb und im Test sowieso, wobei die Administration behauptet, alles ist identisch.
Es schwebt die die Befürchtung im Raum, dass das was auf dem einen Rechner unbekannterweise zu dem Fehler führt und bis jetzt keiner kennt, irgendwann auch auf dem aktiv wird und dann isses zappenduster.
Ich mal Laufprotokolle zur Illustration angefügt, man sieht im einen Fall das hinter "Anzahl Files:" nichts steht, was zu dem Syntaxfehler in der if-Abfrage führt, im anderen Fall eben die Anzahl der aufgelisteten Files, die dann verarbeitet werden, im fehlerhaften Fall allerdings ohne die in der if-Abfrage vorgesehen Bearbeitung,
Die kritischen Stellen sind in der Hardcopy gelb markiert.
Ich gebe jedem Recht, der sagt, dass das nicht sein kann - ich werde aber nicht nachlassen, da trotzdem weiter zu recherchieren.
Leider ist mir als kleinem externen Anwendungsentwickler nicht jeder Zugang zum Environment möglich, deswegen werde ich vermutlich einfach den alten Code anpassen müssen.
Es ist nicht das erste Mal, dass ich erlebe, dass in diesem komplexen Systemen heutzutage eine Fehler erzeugende Konfiguration nicht zu analysieren war,
 

Anhänge

  • SYSOUT_fehlerhafte_Verarbeitung_Y1SEP_MC_output_20250624103500_00001-2.txt
    9,7 KB · Aufrufe: 7
  • SYSOUT_gelungene_Verarbeitung_Y1SEP_MC_output_20250624143000_00003-2.txt
    6,9 KB · Aufrufe: 4
  • 1A257385-1.png
    1A257385-1.png
    37,3 KB · Aufrufe: 8

framp

Moderator
Teammitglied
in dem FILECNT steht defintiv nichts drin, da nützt mir auch kein Hexaldump.
Ich habe mal versucht zu erreichen dass in FILECNT nichts drinsteht. Leider kein Erfolg. wc liefert immer eine Zahl zurück.

Code:
framp@majestix:~/test$ cat ticks.sh
#!/bin/bash
#
set -eo pipefail

cnt() {
    echo "-> $1 <-"
    FILES=`$1`
    FILECNT=`echo $FILES | wc -w`
    echo "FILES: $FILES"
    echo "FILECNT: $FILECNT"
}

cnt "ls -1 *.sh"
cnt ""
cnt $DUMMY
CHINESE="世界+你好"
cnt "echo $CHINESE"

#Add BOM to the new file
printf '\xEF\xBB\xBF' > with_bom.txt
# Append the content of the source file to the new file
echo "世界+你好" >> with_bom.txt
cnt "echo $(<with_bom.txt)"

framp@majestix:~/test$ ./ticks.sh
-> ls -1 *.sh <-
FILES: mwe.sh
ticks.sh
FILECNT: 2
->  <-
FILES:
FILECNT: 0
->  <-
FILES:
FILECNT: 0
-> echo 世界+你好 <-
FILES: 世界+你好
FILECNT: 1
-> echo 世界+你好 <-
FILES: 世界+你好
FILECNT: 1

Deshalb bin ich nicht davon überzeugt dass da nichts drinsteht.

Code:
//mmwsrv01/anwendungen$/BATCH/SEPA/concatxml_mc.sh: Zeile 38: [: 26: Einstelliger (unärer) Operator erwartet.

Wie sieht denn die Codezeile 38 in concatxml_mc.sh aus?
 
Ich habe es auch nicht geschafft, mit dem Code des Skripts mit FILECNT=`echo $FILES | wc -w` etwas anderes in $FILECNT zu bekommen als ungünstigstenfalls 0. Das ist ja, wenn alles korrekt funktioniert, auch der Wert, wenn wc in dem übergebenen String nichts findet - also auf jeden Fall ein numerischer Wert, auch "Zahl" genannt.
Es kommt aber in dem Fehlerfall offenbar etwas anderes zurück: nach meinem Eindruck ein Blank oder auch Low Value - das kann ich nicht checken, weil ich auf den Prod-Server keinen Zugang habe.
Auf jeden Fall kommt etwas zurück, was die Zeile 38: "then if [ $COUNTER != $FILECNT ] so zusammenschiebt, dass die Meldung mit dem fehlenden unären Operator geworfen wird.
Ich habe das im Test damit erreicht, dass ich hart ein Blank in den $FILECNT geschoben habe,. Also liegt die Vermutung nahe, dass auch aus FILECNT=`echo $FILES | wc -w` auch ein Blank kommt. Fest steht aber, dass aus dieser Zuweisung schon mal keine Zahl kommt, dann dann würde die if-Abfrage als syntaktisch korrekt interpretiert.
Das legt aber die Vermutung nahe, dass, wenn man annimmt, dass wc immer ein Zahl liefert, die Zuweisung über die backticks nicht richtig funktioniert, das würd erklären, dass der $FILECNT leer ist.
Ich kann mir auch schwer vorstellen, dass die backtick-Zuweisung "nicht mehr" funktioniert, ich nutze die auch standardmäßig bei basename- oder date-Zuweisungen, aber es sieht in diesem speziellen Fall einfach so aus, so daß für mich die Frage entstand, wodurch könnte das beeinflusst werden ?
 

susejunky

Moderator
Teammitglied
Die kritischen Stellen sind in der Hardcopy gelb markiert.
Ich habe mir Deinen Code-Ausschnitt einmal angesehen und mit den Log-Ausgaben, die im Erfolgsfall erzeugt werden, abgeglichen.

Meines Erachtens passen der von Dir gezeigte Code und die Log-Ausgaben nicht wirklich zusammen (siehe beiliegenden Datei). Aber ich denke es ist besser, wenn ich jetzt an die Forumsmitglieder mit mehr Programmiererfahrung abgebe.
 

Anhänge

  • Fragen_zu_SYSOUT_gelungene_Verarbeitung.txt
    7,9 KB · Aufrufe: 2
Du hast Recht, der Code ist etwas anders, weil der aus meiner Testversion ist - dort habe ich zum Nachgucken den cat eingebaut, den es in echt nicht gibt und die "Anzahl Files..." -Ausgabe entfernt, weil ich im Test dort einiges zur Kontrolle ausgegeben habe. Die entscheidenden Stellen sind aber unverändert.
Anbei eine Hardcopy die zu den SYSOUTS passt, fall es noch interessiert...
 

Anhänge

  • 18527358.png
    18527358.png
    54,7 KB · Aufrufe: 7
...aber nochmal zur Verdeutlichung: es ist an dem Skript nirgends nicht etwas geändert worden, es ist seit ca. dreizehn Jahren problemlos gelaufen, auch wenn es mir vom Coding her nicht gefällt und läuft auch auf allen Environments weiter. Daher lautet die Frage, was ist möglicherweise am Environment, auf dem es nicht nicht mehr korrekt läuft, anders geworden, dass dieser Subprozess mit dem Gravis plötzlich keine Zahl mehr liefert.
 

framp

Moderator
Teammitglied
Code:
//mmwsrv01/anwendungen$/BATCH/SEPA/concatxml_mc.sh: Zeile 38: [: 26: Einstelliger (unärer) Operator erwartet.

Wie sieht denn die Codezeile 38 in concatxml_mc.sh aus?
?

Wie @susejunky schon schreibt: Dein Code passt nicht zu den Logausgaben :-(

Noch ein paar Dinge die mir als Ursache in den Kopf kommen:
1) Ist das Testsystem ein Clone des Prodsystems? Ansonsten kannst Du nicht sicher sein dass Du dieselben Bedingunegn hast.
2) Wird derselbe Nutzer genommen um das Script aufzurufen?
3) Werden dieselben Language Settings genommen?
4) Sind alle globalen bash Settings identisch zwischen Test und Prod?
 
Ja in diese Richtung gingen meine Vermutungen auch, aber wie framp schreibt nutzt wc keinen IFS, Und selbst wenn würde/müsste es 0 zurückliefern Genauso wie die Verwendung auf einen String statt auf eine File nicht der reinen Lehre entspricht, aber doch immer funktioniert hat. Die nicht-numerische Ausgabe, die das Probelm verursacht, sieht nicht nach wc aus.
Die übrigen Fragen kann ich so aus dem Stand nicht beantworten, weil ich von zu Hause aus nicht auf den Prod-Rechner komme, dazu muss ich mich bei jemandem mit Admin-Rechten auf den Schoß setzen - aber diese behaupten ja, das alles gleich ist und bei den settings, die ich bisher angefragt und überprüft habe , war das auch der Fall. Deswegen wäre es schön zu wissen, welche settings genau inspiziert werden müssen, weil sie verdächtigt werden können, genau auf diese Kommandos Einfluss zu haben. Irgendetwas muss sich ja letzte Woche kurz vor dem ersten Auftreten des Problems geändert haben oder geändert worden sein, was von niemandem in dieser Hinsicht ernst genommen wurde. Man wird wohl nicht umhin kommen, alles durchzuflöhen, weil, wie schon geschrieben, möglicherweise auch andere Skripte betroffen sein könnten.
Die Zeile 38 ist meiner letzten Hardcopy numeriert sichtbar, das ist die Zeile mit der nicht funktionierenden If-Abfrage.
 
Oben