Обгортання команди, що включає одинарні та подвійні лапки для іншої команди


10

Нещодавно я дізнався про годинник , але у мене виникають проблеми з його роботою з відносно складними командами.

Наприклад, я хотів би попросити watchвиконувати наступну команду zshкожні три секунди * :

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

як ви бачите, рядок вище включає одинарні лапки, подвійні лапки, серед інших спеціальних символів.

Тому я спробував:

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

але тоді я отримав:

не знайдено збігів для x in! @ # $ # ....; зроблено

Я пробував інші комбінації без успіху. Ось одна з таких спроб:

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

що також призводить до подібної помилки.

Будь-які ідеї, як зробити цю роботу?


* Я також був би втручений у рішення, які працюють надbash

Відповіді:


16

Загальна порада: якщо у вас є два рівні гніздування, уникайте використання одинарних лапок у внутрішній команді та використовуйте одиничні лапки навколо зовнішньої команди.

Додаткова порада: не використовуйте зворотні посилання - `…` - для виконання коду, а використовуйте $(…)навколо нього. Дуже-круглі дужки - це майже DWIM ("Зроби що я маю на увазі"), коли мова йде про вкладені котирування; Зворотні котирування мають таємні, залежні від оболонки правила.

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

Якщо вам потрібні одиничні лапки всередині однієї котируваної команди, ви можете використовувати '\''. Подумайте про цих чотирьох символів як про те, як цитувати єдину цитату в одних цитатах, хоча технічно кажучи, це побудовано як кінець рядка з одним котируванням, додайте буквальну єдину цитату і заведіть новий рядок з одним котируванням (все ще додається до поточне слово).

У складніших випадках або старанно рахуйте лапки, або визначайте тимчасові змінні.

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

Ця відповідь не характерна для zsh. Zsh тут не приносить нічого серйозного. Ви можете зберегти трохи цитування, оскільки немає необхідності в подвійних лапочках навколо підстановок команд, а іноді існують способи використання вбудованих, а не зовнішніх команд, що зменшують потреби в котируванні, але основні проблеми такі ж, як і в інших оболонках.

О, і до речі, зверніть увагу, що watchбуде виконуватися ваша команда в sh, а не в zsh. Якщо ви хочете виконати команду в zsh, вам потрібно запустити

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

на Debian / Ubuntu та

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

(ще більше цитування!) в інших місцях.


Дякую @Gilles Це було дуже корисно. Цікаво, watchщо не йде -xні з -cпараметрами, ні на моїй машині. Я подивився це в Інтернеті і не знайшов жодної сторінки чоловіка, яка б їх згадувала. Що роблять ці варіанти?
Амеліо Васкес-Рейна

1
@intrpc -xкаже watchне передавати команду через оболонку. Я щойно з’ясував, що це специфічно для Debian / Ubuntu, хоча це не вказано як таке. Це -cпередається zsh, не watch.
Жил 'ТАК - перестань бути злим'

@Gilles -xі -execваріанти є в моєму watch(на gentoo), тому це, безумовно, не характерно для Debian. Можливо, ви порівняли з якоюсь іншою версією watch? Шахта походить з пакету propps .
rozcietrzewiacz

1
@rozcietrzewiacz також watchпоходить від procpsDebian. Офіційне джерело не має --exec. Пакет у Debian (та похідні, включаючи Ubuntu) додає параметр у специфічний для Debian патч ( watch_exec_beep.patch; це "патч Mortys watch exec" від помилки №410967 ). Можливо, Gentoo прийняв подібний патч.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.