การคาดคะเนของคุณว่าเป็นssh
ตัวเองที่ส่งคืนสถานะทางออก 255 ถูกต้อง ssh
หน้าคนกล่าวว่า:
ออกจาก ssh ด้วยสถานะออกของคำสั่งระยะไกลหรือ 255 หากมีข้อผิดพลาดเกิดขึ้น
หากคุณเพียงแค่เรียกใช้ssh pi@10.20.0.10 "pkill -f asdf"
คุณน่าจะได้รับสถานะการออก1
ซึ่งสอดคล้องกับpkill
สถานะของ“ ไม่มีกระบวนการที่ตรงกัน ”
ส่วนที่ท้าทายคือการเข้าใจว่าทำไมข้อผิดพลาดเกิดขึ้นกับ SSH เมื่อคุณเรียกใช้
ssh pi@10.20.0.10 "pkill -f asdf || true"
คำสั่งรีโมต SSH
เซิร์ฟเวอร์ SSH เรียกใช้เชลล์เพื่อเรียกใช้คำสั่งระยะไกล นี่คือตัวอย่างของการกระทำนี้:
$ ssh server "ps -elf | tail -5"
4 S root 35323 1024 12 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony [priv]
5 S anthony 35329 35323 0 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony@notty
0 S anthony 35330 35329 0 80 0 - 28283 do_wai 12:01 ? 00:00:00 bash -c ps -elf | tail -5
0 R anthony 35341 35330 0 80 0 - 40340 - 12:01 ? 00:00:00 ps -elf
0 S anthony 35342 35330 0 80 0 - 26985 pipe_w 12:01 ? 00:00:00 tail -5
โปรดทราบว่าเชลล์เริ่มต้นคือbash
และว่าคำสั่งระยะไกลไม่ใช่คำสั่งง่าย ๆ แต่เป็นไพพ์ไลน์ “ ลำดับของคำสั่งหนึ่งคำสั่งหรือมากกว่านั้นคั่นด้วยตัวดำเนินการควบคุม|
”
Bash shell นั้นฉลาดพอที่จะรู้ได้ว่าหากคำสั่งนั้นถูกส่งผ่านโดย-c
ตัวเลือกนั้นเป็นคำสั่งง่าย ๆมันสามารถปรับให้เหมาะสมโดยไม่ทำการปลอมกระบวนการใหม่เช่นมันexec
เป็นคำสั่งง่าย ๆโดยตรงแทนที่จะผ่านขั้นตอนพิเศษ ของfork
ไอเอ็นจีก่อนที่มันจะexec
s นี่คือตัวอย่างของสิ่งที่เกิดขึ้นเมื่อคุณเรียกใช้คำสั่งง่าย ๆ ระยะไกล ( ps -elf
ในกรณีนี้):
$ ssh server "ps -elf" | tail -5
1 S root 34740 2 0 80 0 - 0 worker 11:49 ? 00:00:00 [kworker/0:1]
1 S root 34762 2 0 80 0 - 0 worker 11:50 ? 00:00:00 [kworker/0:3]
4 S root 34824 1024 31 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony [priv]
5 S anthony 34829 34824 0 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony@notty
0 R anthony 34830 34829 0 80 0 - 40340 - 11:51 ? 00:00:00 ps -elf
ฉันเคยเจอพฤติกรรมนี้มาก่อน แต่ฉันไม่พบการอ้างอิงที่ดีกว่าคำตอบ AskUbuntuนี้
พฤติกรรม pkill
เนื่องจากpkill -f asdf || true
ไม่ได้เป็นคำสั่งง่ายๆ (เป็นรายการคำสั่ง ), การเพิ่มประสิทธิภาพดังกล่าวข้างต้นไม่สามารถเกิดขึ้นดังนั้นเมื่อคุณทำงานssh pi@10.20.0.10 "pkill -f asdf || true"
ที่ส้อมกระบวนการและการบริหารsshd
bash -c "pkill -f asdf || true"
ตามคำตอบของ ctx pkill
จะไม่ฆ่ากระบวนการของตัวเอง อย่างไรก็ตามมันจะฆ่ากระบวนการอื่นใดที่บรรทัดคำสั่งตรงกับ-f
รูปแบบ bash -c
คำสั่งตรงกับรูปแบบนี้จึงฆ่ากระบวนการนี้ - พ่อแม่ของตัวเอง (ที่มันเกิดขึ้น)
จากนั้นเซิร์ฟเวอร์ SSH จะเห็นว่ากระบวนการเชลล์ที่เริ่มต้นขึ้นเพื่อเรียกใช้คำสั่งระยะไกลถูกฆ่าโดยไม่คาดคิดดังนั้นจึงรายงานข้อผิดพลาดไปยังไคลเอ็นต์ SSH
pkill
ฆ่ากระบวนการเปลือกแม่เพราะรายการหาเรื่องตรงกับ regexp ผมจะยกคำคัดค้านคำศัพท์:x || y
คือไม่คำสั่งผสมมันเป็นรายการคำสั่ง