
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, TASKNAME
es enthält Our Special Task_4
, dann STOP_SEARCH_STR
ist es auf gesetzt 'for Our Special Task_4'
, einschließlich dieser Anführungszeichen. Das ist, was Ihr echo
zeigt.
Wenn Sie ausführen grep -F "$STOP_SEARCH_STR" "$TEMP"/draft
, geben Sie grep
die 'for Our Special Task_4'
zu suchende Zeichenfolge an. Diese Zeichenfolge ist in der Datei nicht vorhanden, daher stimmen keine Zeilen überein und grep
es 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 somecmd
direkt 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")"