Enveloppant une command qui inclut des guillemets simples et doubles pour une autre command

J'ai récemment appris sur la montre , mais j'ai du mal à le faire fonctionner avec des commands relativement sophistiquées.

Par exemple, j'aimerais requestr à watch d'exécuter la command suivante sur zsh toutes les trois secondes * :

 for x in `command_1 | grep keyword | cut -d' ' -f1`; do command_2 "word[word=number]" $x; done 

comme vous pouvez le voir, la ligne ci-dessus comprend des guillemets simples, des guillemets doubles, entre autres caractères spéciaux.

Alors j'ai essayé:

 watch -n 3 "for x in `my_command | grep keyword | cut -d' ' -f1`; do command2 "rusage[mem=7000]" $x; done" 

mais alors j'ai eu:

aucun résultat trouvé pour x dans! @ # $ # ….; terminé

J'ai essayé d'autres combinaisons sans succès. Voici une de ces tentatives:

 watch -n 3 "for x in $(bjobs -w | grep pre_seg | cut -d' ' -f1); do bmod -R "rusage[mem=7000]" $x; done" 

ce qui entraîne également une erreur similaire.

Des idées pour faire ce travail?


* Je serais aussi intéressé par les solutions qui fonctionnent sur bash

Astuce générale: si vous avez deux niveaux d'imbrication, évitez d'utiliser des guillemets simples dans la command interne et utilisez des guillemets simples autour de la command externe.

Astuce supplémentaire: n'utilisez pas de tics arrières – `…` – pour exécuter du code, utilisez plutôt $(…) autour d'elle. Le dollar-parenthèses est à peu près DWIM («fais ce que je veux dire») quand il s'agit de citations nestedes; les backquotes ont des règles arcanes, dépendant de la coquille.

 watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done' 

Si vous avez besoin de guillemets simples dans une seule command, vous pouvez utiliser '\'' . Pensez à ces quatre caractères comme le moyen de citer un guillemet simple à l'intérieur de guillemets simples, bien que techniquement parlant, ceci soit construit comme terminant la guillemets, append un guillemet simple littéral et commencer une nouvelle guillemets guillemets mot courant).

Pour les cas plus complexes, countz minutieusement les guillemets ou définissez des variables temporaires.

 cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" $x; done' watch_cmd='watch -n 3 "$cmd"' 

Cette réponse n'est pas spécifique à zsh. Zsh n'apporte rien de majeur ici. Vous pouvez sauvegarder un peu de citation car il n'y a pas besoin de guillemets doubles sur les substitutions de commands et parfois il y a des façons d'utiliser des commands embeddedes plutôt que des commands externes qui réduisent les besoins de citation mais les problèmes sous-jacents sont les mêmes que dans d'autres shells.

Oh, et en passant, notez que watch exécutera votre command en sh , pas en zsh. Si vous voulez exécuter la command dans zsh, vous devez exécuter

 watch -n 3 -x zsh -c "$cmd" 

sur Debian / Ubuntu, et

 watch -n 3 'exec zsh -c "$cmd"' 

(encore plus de citations!) ailleurs.