Gói một lệnh bao gồm dấu ngoặc đơn và dấu ngoặc kép cho lệnh khác


10

Gần đây tôi đã biết về đồng hồ , nhưng gặp khó khăn khi làm cho nó hoạt động với các lệnh tương đối tinh vi.

Ví dụ: tôi muốn yêu cầu watchchạy lệnh sau zshcứ sau ba giây * :

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

như bạn có thể thấy dòng trên bao gồm dấu ngoặc đơn, dấu ngoặc kép, trong số các ký tự đặc biệt khác.

Vì vậy, tôi đã cố gắng:

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

nhưng sau đó tôi đã nhận được:

không tìm thấy kết quả trùng khớp nào cho x in! @ # $ # ....; làm xong

Tôi đã thử các kết hợp khác mà không thành công. Đây là một trong những nỗ lực đó:

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

Điều này cũng dẫn đến một lỗi tương tự.

Bất kỳ ý tưởng làm thế nào để làm cho công việc này?


* Tôi cũng sẽ được xen vào các giải pháp hoạt động trênbash

Câu trả lời:


16

Mẹo chung: nếu bạn có hai cấp độ lồng nhau, tránh sử dụng dấu ngoặc đơn trong lệnh bên trong và sử dụng dấu ngoặc đơn xung quanh lệnh bên ngoài.

Mẹo bổ sung: không sử dụng backticks - `…` - để thực thi mã, thay vào đó hãy sử dụng $(…)xung quanh nó. Dấu ngoặc đơn là khá nhiều DWIM ('Hãy làm theo ý tôi') khi nói đến dấu ngoặc kép; backquote có quy tắc phức tạp, phụ thuộc vỏ.

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

Nếu bạn cần một dấu ngoặc đơn bên trong một lệnh được trích dẫn, bạn có thể sử dụng '\''. Hãy nghĩ về bốn ký tự này như là cách trích dẫn một trích dẫn bên trong các trích dẫn đơn, mặc dù về mặt kỹ thuật, điều này được xây dựng dưới dạng kết thúc chuỗi trích dẫn đơn, nối thêm một trích dẫn bằng chữ và bắt đầu một chuỗi trích dẫn đơn mới (vẫn được thêm vào từ hiện tại).

Đối với các trường hợp phức tạp hơn, hãy cẩn thận đếm các trích dẫn hoặc xác định các biến tạm thời.

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

Câu trả lời này không cụ thể cho zsh. Zsh không mang bất cứ thứ gì quan trọng vào đây. Bạn có thể tiết kiệm một chút trích dẫn vì không cần trích dẫn kép xung quanh thay thế lệnh và đôi khi có nhiều cách để sử dụng các lệnh dựng sẵn thay vì các lệnh bên ngoài làm giảm nhu cầu trích dẫn, nhưng các vấn đề cơ bản cũng giống như trong các shell khác.

Ồ, và nhân tiện, lưu ý rằng watchsẽ thực thi lệnh của bạn sh, không phải trong zsh. Nếu bạn muốn thực thi lệnh trong zsh, bạn cần chạy

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

trên Debian / Ubuntu và

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

(thậm chí nhiều trích dẫn!) ở nơi khác.


Cảm ơn @Gilles. Điều đó rất hữu ích. Thật thú vị watchkhông đi kèm với các tùy chọn -xcũng không có -ctrên máy của tôi. Tôi đã tìm nó trên mạng và không tìm thấy bất kỳ trang nào đề cập đến chúng. Những lựa chọn này làm gì?
Amelio Vazquez-Reina

1
@intrpc -xbảo watchkhông truyền lệnh qua shell. Tôi mới phát hiện ra rằng điều này là dành riêng cho Debian / Ubuntu, mặc dù nó không được chỉ định như vậy. Các -cđược truyền đến zsh, không phải để watch.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Cả -x-execcác tùy chọn đều tồn tại trong watch(trên gentoo) của tôi, vì vậy đây chắc chắn không phải là đặc trưng của Debian. Có lẽ bạn so với một số phiên bản khác của watch? Của tôi đến từ gói Procps .
rozcietrzewiacz

1
@rozcietrzewiacz cũng watchxuất phát từ procpsDebian. Nguồn chính thức không có --exec. Gói trong Debian (và các dẫn xuất bao gồm Ubuntu) thêm tùy chọn trong một bản vá dành riêng cho Debian ( watch_exec_beep.patch; đó là đồng hồ Mort Mortys thực thi bản vá lỗi từ lỗi # 410967 ). Gentoo có thể đã áp dụng một bản vá tương tự.
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.