Ich habe vor kurzem etwas über Watch gelernt, habe aber Probleme damit, es mit relativ komplizierten Befehlen zum Laufen zu bringen.
Zum Beispiel würde ich gerne watch
fragen um den folgenden Befehl auf zsh
auszuführen alle drei Sekunden:
for x in `command_1 | grep keyword | cut -d' ' -f1`; do command_2 "word[word=number]" $x; done
Wie Sie sehen können, enthält die obige Zeile neben anderen Sonderzeichen einfache Anführungszeichen, doppelte Anführungszeichen.
Also habe ich versucht:
watch -n 3 "for x in `my_command | grep keyword | cut -d' ' -f1`; do command2 "rusage[mem=7000]" $x; done"
aber dann bekam ich:
keine Übereinstimmungen für x gefunden in [email protected]#$# ….; erledigt
Andere Kombinationen habe ich ohne Erfolg probiert. Hier ist einer dieser Versuche:
watch -n 3 "for x in $(bjobs -w | grep pre_seg | cut -d' ' -f1); do bmod -R "rusage[mem=7000]" $x; done"
was ebenfalls zu einem ähnlichen Fehler führt.
Irgendwelche Ideen, wie das funktioniert?
Ich wäre auch an Lösungen interessiert, die auf bash
funktionieren
Akzeptierte Antwort:
Allgemeiner Tipp:Wenn Sie zwei Verschachtelungsebenen haben, vermeiden Sie einfache Anführungszeichen im inneren Befehl und verwenden Sie einfache Anführungszeichen um den äußeren Befehl.
Zusätzlicher Tipp:keine Backticks verwenden – `…`
– Um Code auszuführen, verwenden Sie stattdessen $(…)
um es herum. Dollar-Klammern sind so ziemlich DWIM („Do what I mean“), wenn es um verschachtelte Anführungszeichen geht; Backquotes haben obskure, Shell-abhängige Regeln.
watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
Wenn Sie einfache Anführungszeichen innerhalb eines Befehls mit einfachen Anführungszeichen benötigen, können Sie '''
verwenden . Stellen Sie sich diese vier Zeichen als Möglichkeit vor, ein einfaches Anführungszeichen in einfache Anführungszeichen zu setzen, obwohl dies technisch gesehen so konstruiert ist, dass die Zeichenfolge in einfachen Anführungszeichen beendet wird, ein wörtliches einfaches Anführungszeichen angehängt wird und eine neue Zeichenfolge in einfachen Anführungszeichen beginnt (immer noch an die aktuelles Wort).
Für komplexere Fälle können Sie entweder die Anführungszeichen sorgfältig zählen oder temporäre Variablen definieren.
cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
watch_cmd='watch -n 3 "$cmd"'
Diese Antwort ist nicht spezifisch für zsh. Zsh bringt hier nichts Großes. Sie können ein wenig Anführungszeichen sparen, da keine doppelten Anführungszeichen um Befehlsersetzungen erforderlich sind, und manchmal gibt es Möglichkeiten, integrierte anstelle von externen Befehlen zu verwenden, die den Bedarf an Anführungszeichen reduzieren, aber die zugrunde liegenden Probleme sind die gleichen wie in anderen Shells.
Oh, und übrigens, beachten Sie, dass watch
führt Ihren Befehl in sh
aus , nicht in zsh. Wenn Sie den Befehl in zsh ausführen möchten, müssen Sie ausführen
watch -n 3 -x zsh -c "$cmd"
auf Debian/Ubuntu und
export cmd
watch -n 3 'exec zsh -c "$cmd"'
(noch mehr zitieren!) an anderer Stelle.
Verwandte:Den Wert einer Variablen in Bash in Anführungszeichen setzen oder nicht?