Bash-String-Auswertung unklar

Bash-String-Auswertung unklar

Beachten Sie Folgendes in einem Bash-Skript:

STOP_SEARCH_STR="'""for $TASKNAME""'"
echo $STOP_SEARCH_STR               # prints 'for Our Special Task_4'
echo "$STOP_SEARCH_STR"             # prints 'for Our Special Task_4'
echo "grep -F "$STOP_SEARCH_STR" "$TEMP"/draft" # prints grep -F 'for Our Special Task_4' /tmp/draft
echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft)"  # prints nothing!
echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")  # prints nothing!

Und folgender Inhalt in der Textdatei $TEMP/draft:

2019-11-21 08:13:58,825 Task started: 'Our Special Task_4' of type 'Our - Special Task' 
2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

Wenn ichmanuellWenn ich den Befehl eingebe grep -F 'for Our Special Task_4' /tmp/draft, erhalte ich die zweite Zeile im Entwurf der Textdatei:

2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

Aber die letzten beiden Befehle oben (innerhalb eines Bash-Skripts) drucken nichts!

Irgendeine Idee, warum?

Antwort1

Anführungszeichen haben nach der Erweiterung einer Variable keine besondere Bedeutung.

Angenommen, TASKNAMEes enthält Our Special Task_4, dann STOP_SEARCH_STRist es auf gesetzt 'for Our Special Task_4', einschließlich dieser Anführungszeichen. Das ist, was Ihr echozeigt.

Wenn Sie ausführen grep -F "$STOP_SEARCH_STR" "$TEMP"/draft, geben Sie grepdie 'for Our Special Task_4'zu suchende Zeichenfolge an. Diese Zeichenfolge ist in der Datei nicht vorhanden, daher stimmen keine Zeilen überein und grepes wird nichts gedruckt.

Entfernen Sie die Anführungszeichen, Sie suchen nicht danach:

task="Our Special Task_4"
str="for $task"
grep -F "$str" "$TEMP/draft"

Hinweis: SieTunWenn Sie die Variablenerweiterung in Anführungszeichen setzen möchten "$str"oder "$STOP_SEARCH_STR"eine Worttrennung verhindern möchten, sieheWarum gerät mein Shell-Skript ins Stocken, wenn es sich um Leerzeichen oder andere Sonderzeichen handelt?

Wenn dumanuellGeben Sie den Befehl ein grep -F 'for Our Special Task_4' /tmp/draft. Die Anführungszeichen sind Teil der Shell-Syntax und entfernen effektiv die spezielle Bedeutung der Leerzeichen darin. Dies unterscheidet sich von Anführungszeichen innerhalb einer Variablen, die sich wie normale Zeichen verhalten.


Nebenbei bemerkt: 1) echo "$(somecmd)"ist normalerweise überflüssig, Sie könnten es einfach somecmddirekt ausführen. 2) Hier: echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft"), aufgrund der Art und Weise, wie die Anführungszeichen das Leerzeichen umgeben, versuchen Sie, einen Befehl namens auszuführen grep -F 'for. Sie sollten dafür wahrscheinlich eine Fehlermeldung erhalten:

$ echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")
bash: grep -F 'for: command not found

Antwort2

Sie sollten diese Zeile ändern:

STOP_SEARCH_STR="'""for $TASKNAME""'"

zu dieser Zeile (ja, keine einfachen Anführungszeichen erforderlich, sie sind nicht nützlich):

STOP_SEARCH_STR="for $TASKNAME"

Und verwenden Sie diese Zeile im Skript (ja, in Anführungszeichen wie gezeigt):

grep -F "$STOP_SEARCH_STR" "$TEMP"/draft

Wenn Sie ein Echo hinzufügen möchten/müssen (was überflüssig ist und sogar Probleme verursachen kann), verwenden Sie diese Zeile (ja, setzen Sie alle Erweiterungen (Variablen und Subshell) in Anführungszeichen):

echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")"

verwandte Informationen