Di recente ho appreso dell'orologio, ma ho problemi a farlo funzionare con comandi relativamente sofisticati.
Ad esempio, vorrei chiedere a watch
per eseguire il seguente comando su zsh
ogni tre secondi:
for x in `command_1 | grep keyword | cut -d' ' -f1`; do command_2 "word[word=number]" $x; done
come puoi vedere, la riga sopra include virgolette singole, virgolette doppie e altri caratteri speciali.
Quindi ho provato:
watch -n 3 "for x in `my_command | grep keyword | cut -d' ' -f1`; do command2 "rusage[mem=7000]" $x; done"
ma poi ho ottenuto:
nessuna corrispondenza trovata per x in [email protected]#$# ….; fatto
Ho provato altre combinazioni senza successo. Ecco uno di quei tentativi:
watch -n 3 "for x in $(bjobs -w | grep pre_seg | cut -d' ' -f1); do bmod -R "rusage[mem=7000]" $x; done"
che si traduce anche in un errore simile.
Qualche idea su come farlo funzionare?
Sarei anche interessato a soluzioni che funzionano su bash
Risposta accettata:
Suggerimento generale:se hai due livelli di annidamento, evita di usare virgolette singole nel comando interno e usa virgolette singole attorno al comando esterno.
Suggerimento aggiuntivo:non utilizzare backtick – `…`
– per eseguire il codice, usa invece $(…)
intorno ad esso. Le parentesi in dollari sono praticamente DWIM ("Fai quello che intendo") quando si tratta di virgolette nidificate; le virgolette hanno regole arcane, dipendenti dalla shell.
watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
Se hai bisogno di virgolette singole all'interno di un comando con virgolette singole, puoi utilizzare '''
. Pensa a questi quattro caratteri come al modo per citare una virgoletta singola tra virgolette singole, anche se tecnicamente parlando questo è costruito come terminare la stringa tra virgolette singole, aggiungere una virgoletta singola letterale e iniziare una nuova stringa tra virgolette singole (ancora aggiunta al parola corrente).
Per casi più complessi, conta scrupolosamente le virgolette o definisci variabili temporanee.
cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
watch_cmd='watch -n 3 "$cmd"'
Questa risposta non è specifica per zsh. Zsh non porta nulla di importante qui. Puoi risparmiare un po 'di citazioni perché non sono necessarie virgolette intorno alle sostituzioni dei comandi e talvolta ci sono modi per utilizzare comandi integrati anziché esterni che riducono le esigenze di virgolette, ma i problemi sottostanti sono gli stessi di altre shell.
Oh, e comunque, nota che watch
eseguirà il tuo comando in sh
, non in zsh. Se vuoi eseguire il comando in zsh, devi eseguire
watch -n 3 -x zsh -c "$cmd"
su Debian/Ubuntu e
export cmd
watch -n 3 'exec zsh -c "$cmd"'
(ancora più citando!) altrove.
Correlati:racchiudere e non racchiudere il valore di una variabile tra virgolette in bash?