ไม่มีคือเข้าใจผิดวิธีการตรวจสอบถ้า STDIN, STDOUT หรือ STDERR มีการประปา / ssh
จากสคริปต์ของคุณส่วนใหญ่เพราะของโปรแกรมเช่น
สิ่งที่ "ปกติ" ทำงาน
ตัวอย่างเช่นโซลูชัน bash ต่อไปนี้ทำงานอย่างถูกต้องในเชลล์แบบโต้ตอบ:
[[ -t 1 ]] && \
echo 'STDOUT is attached to TTY'
[[ -p /dev/stdout ]] && \
echo 'STDOUT is attached to a pipe'
[[ ! -t 1 && ! -p /dev/stdout ]] && \
echo 'STDOUT is attached to a redirection'
แต่มันก็ไม่ได้ผลเสมอไป
อย่างไรก็ตามเมื่อเรียกใช้งานคำสั่งนี้เป็นคำสั่งที่ไม่ใช่ TTY ssh
สตรีม STD จะดูเหมือนว่ากำลังถูกไพพ์ เพื่อแสดงสิ่งนี้ใช้ STDIN เพราะง่ายกว่า:
# CORRECT: Forced-tty mode correctly reports '1', which represents
# no pipe.
ssh -t localhost '[[ -p /dev/stdin ]]; echo ${?}'
# CORRECT: Issuing a piped command in forced-tty mode correctly
# reports '0', which represents a pipe.
ssh -t localhost 'echo hi | [[ -p /dev/stdin ]]; echo ${?}'
# INCORRECT: Non-tty mode reports '0', which represents a pipe,
# even though one isn't specified here.
ssh -T localhost '[[ -p /dev/stdin ]]; echo ${?}'
ทำไมมันถึงสำคัญ
นี่เป็นเรื่องใหญ่เพราะมันบอกเป็นนัยว่าไม่มีวิธีใดที่สคริปต์ทุบตีจะบอกว่าssh
คำสั่งที่ไม่ใช่ tty กำลังถูกไพพ์หรือไม่ โปรดทราบว่าพฤติกรรมที่โชคร้ายนี้ถูกนำมาssh
ใช้เมื่อเริ่มต้นเวอร์ชันล่าสุดโดยใช้ไพพ์สำหรับ non-TTY STDIO [[ -S ]]
รุ่นก่อนที่ใช้ซ็อกเก็ตซึ่งอาจจะแตกต่างจากภายในทุบตีโดยใช้
เมื่อมันสำคัญ
ข้อ จำกัด cat
นี้ทำให้เกิดปัญหาตามปกติเมื่อคุณต้องการที่จะเขียนสคริปต์ทุบตีที่มีลักษณะการทำงานคล้ายกับยูทิลิตี้ที่รวบรวมเช่น ยกตัวอย่างเช่นcat
ช่วยให้พฤติกรรมที่มีความยืดหยุ่นต่อไปนี้ในการจัดการแหล่งป้อนข้อมูลต่างๆพร้อมกันและเป็นพอสมาร์ทเพื่อตรวจสอบว่ามันจะได้รับการป้อนข้อมูลประปาไม่คำนึงถึงว่าไม่ใช่ TTY หรือบังคับ TTY ssh
จะถูกใช้:
ssh -t localhost 'echo piped | cat - <( echo substituted )'
ssh -T localhost 'echo piped | cat - <( echo substituted )'
คุณสามารถทำอะไรแบบนั้นถ้าคุณสามารถกำหนดได้อย่างน่าเชื่อถือว่าท่อมีส่วนเกี่ยวข้องหรือไม่ มิฉะนั้นการเรียกใช้งานคำสั่งที่อ่าน STDIN เมื่อไม่มีอินพุตจากไพพ์หรือการเปลี่ยนเส้นทางจะส่งผลให้สคริปต์หยุดทำงานและรออินพุต STDIN
สิ่งอื่น ๆ ที่ไม่ทำงาน
ในการพยายามที่จะแก้ปัญหานี้ฉันได้ดูเทคนิคต่าง ๆ ที่ไม่สามารถแก้ปัญหาได้รวมถึงเทคนิคที่เกี่ยวข้อง:
- การตรวจสอบตัวแปรสภาพแวดล้อม SSH
- ใช้
stat
อธิบายไฟล์ on / dev / stdin
- ตรวจสอบโหมดโต้ตอบผ่านทาง
[[ "${-}" =~ 'i' ]]
- ตรวจสอบสถานะ tty ผ่านทาง
tty
และtty -s
- ตรวจสอบ
ssh
สถานะผ่าน[[ "$(ps -o comm= -p $PPID)" =~ 'sshd' ]]
โปรดทราบว่าหากคุณใช้ระบบปฏิบัติการที่สนับสนุน/proc
ระบบไฟล์เสมือนคุณอาจโชคดีที่ติดตามลิงก์สัญลักษณ์สำหรับ STDIO เพื่อตรวจสอบว่ามีการใช้ไปป์หรือไม่ อย่างไรก็ตาม/proc
ไม่ใช่โซลูชันข้ามแพลตฟอร์มที่รองรับ POSIX
ฉันน่าสนใจอย่างมากในการแก้ปัญหานี้ดังนั้นโปรดแจ้งให้เราทราบหากคุณคิดว่ามีเทคนิคอื่นใดที่อาจใช้งานได้ดีกว่าโดยใช้โซลูชัน POSIX ที่ทำงานบนทั้ง Linux และ BSD