การตัดคำสั่งที่มีเครื่องหมายคำพูดเดี่ยวและคู่สำหรับคำสั่งอื่น


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

เคล็ดลับทั่วไป: หากคุณมีการซ้อนสองระดับให้หลีกเลี่ยงการใช้เครื่องหมายคำพูดเดี่ยวในคำสั่งด้านในและใช้เครื่องหมายคำพูดเดี่ยวรอบคำสั่งด้านนอก

เคล็ดลับเพิ่มเติม: อย่าใช้ backticks - `…` - เพื่อรันโค้ดแทนที่จะใช้$(…)มัน ดอลลาร์ - วงเล็บคือ DWIM ('ทำในสิ่งที่ฉันหมายถึง') เมื่อพูดถึงคำพูดซ้อน backquotes มีกฎที่ขึ้นอยู่กับความลับของเชลล์

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บนเครื่องของฉัน ฉันค้นหาออนไลน์และไม่พบหน้าเว็บใด ๆ ที่พูดถึงพวกเขา ตัวเลือกเหล่านี้ทำอะไร
Amelio Vazquez-Reina

1
@intrpc -xบอกwatchไม่ให้ส่งคำสั่งผ่านเชลล์ ฉันเพิ่งพบว่านี่เป็นเฉพาะ Debian / Ubuntu แม้ว่าจะไม่ได้ระบุเช่นนี้ -cถูกส่งผ่านไปไม่ได้ที่จะzsh watch
Gilles 'หยุดชั่วร้าย'

@Gilles The -xและ-execตัวเลือกทั้งสองมีอยู่ในของฉันwatch(ใน gentoo) ดังนั้นนี่จึงไม่ใช่เดเบียนเฉพาะ บางทีคุณอาจเปรียบเทียบกับรุ่นอื่น ๆ ของwatch? ของฉันมาจากแพ็คเกจprocps
rozcietrzewiacz

1
@rozcietrzewiacz watchมาจากprocpsDebian ด้วย แหล่งที่มาอย่างเป็นทางการ--execไม่ได้ แพ็คเกจใน Debian (และสัญญาซื้อขายล่วงหน้ารวมถึง Ubuntu) เพิ่มตัวเลือกในแพทช์เฉพาะของ Debian ( watch_exec_beep.patchนั่นคือ“ Mortys watch exec patch” จากbug # 410967 ) Gentoo อาจนำแพทช์ที่คล้ายกันมาใช้
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.