GNU/Linux >> Linux Esercitazione >  >> Linux

Avvolgere un comando che include virgolette singole e doppie per un altro comando?

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?
Linux
  1. Rimozione di virgolette singole e doppie in una stringa utilizzando solo i comandi bash/standard di Linux

  2. Come creare una directory e dare il permesso in un singolo comando

  3. comando bash alias con virgolette singole e doppie

  4. Che cos'è il doppio punto (..) e il singolo punto (.) in Linux?

  5. grep per termine ed escludi un altro termine

Utilizzo di drush per il backup/ripristino e la migrazione del sito Drupal

Installa il sottosistema Windows per Linux con un comando singolo

50 Comando grep produttivo e pratico per gli appassionati di Linux

Comando Linux Head Tutorial ed esempi per principianti

Impostazione pipefail per un singolo comando con pipe

Apri la pagina man e cerca la stringa in un singolo comando