ฉันจะเช็คอินทุบตีได้อย่างไรถ้าเชลล์ทำงานในโหมดอินเตอร์แอคทีฟ


45

ฉันจะบอกได้อย่างไร (ใน~/.bashrc) ว่าฉันกำลังทำงานในโหมดอินเตอร์แอคทีฟหรือว่าดำเนินการคำสั่งผ่าน ssh ฉันต้องการหลีกเลี่ยงการพิมพ์ ANSI escape sequences ด้วย.bashrcหากเป็นลำดับหลัง


การเลือกว่าจะพิมพ์ลำดับหนีหรือไม่ดีกว่าที่จะขึ้นอยู่กับมูลค่า $ TERM และไม่ได้อยู่ในการโต้ตอบของเปลือก ตัวแปรนี้ระบุความสามารถของไคลเอ็นต์เทอร์มินัลซึ่งเป็นส่วนหนึ่งที่ตีความลำดับของการหลีกเลี่ยง
yrk

คำตอบ:


52

ตามman bash:

มีการตั้งค่า PS1 และ $ - รวม i หาก bash เป็นแบบโต้ตอบอนุญาตให้เชลล์สคริปต์หรือไฟล์เริ่มต้นเพื่อทดสอบสถานะนี้

ดังนั้นคุณสามารถใช้:

if [[ $- == *i* ]]
then
    do_interactive_stuff
fi

นอกจากนี้:

เมื่อเชลล์เชิงโต้ตอบที่ไม่ใช่เชลล์ล็อกอินเริ่มทำงาน bash จะอ่านและดำเนินการคำสั่งจาก /etc/bash.bashrc และ ~ / .bashrc หากมีไฟล์เหล่านี้อยู่

ดังนั้นจึง~/.bashrcมีที่มาสำหรับเชลล์แบบโต้ตอบเท่านั้น บางครั้งผู้คนก็มาจาก~/.bash_profileหรือ~/.profileที่ไม่ถูกต้องเพราะมันรบกวนพฤติกรรมที่คาดหวัง หากคุณต้องการลดความยุ่งยากในการบำรุงรักษารหัสที่ใช้กันทั่วไปคุณควรใช้ไฟล์แยกต่างหากเพื่อเก็บรหัสทั่วไปและแหล่งที่มาของรหัสนั้นแยกต่างหากจากไฟล์ rc

เป็นการดีที่สุดถ้าไม่มีเอาต์พุตไปยัง stdout จากrcไฟล์ล็อกอินเช่น~/.bash_profileหรือ~/.profileเนื่องจากสามารถรบกวนการทำงานที่เหมาะสมของrsyncตัวอย่าง

ในกรณีใด ๆ ก็ยังคงเป็นความคิดที่ดีในการทดสอบการโต้ตอบเนื่องจากการกำหนดค่าที่ไม่ถูกต้องอาจมีอยู่


7
โปรดทราบว่า $ - อาจมี i ไม่จำเป็นต้องเท่ากัน ฉันใช้[[ $- =~ i ]] && echo interactive
Alex Howansky

1
@AlexHowansky: เครื่องหมายดอกจันในการทดสอบความเท่าเทียมทำให้การทดสอบประกอบด้วยi
Dennis Williamson

โอ้ว้าวไม่ได้สังเกตเห็นพวกมันดูเหมือนเครื่องหมายคำพูดคู่บนจอมอนิเตอร์ของฉัน อาจเป็นเวลาที่จะเพิ่มขนาดตัวอักษร <อายุมากขึ้น>
Alex Howansky

บางครั้งผู้คนก็มาจาก~/.bash_profileหรือ~/.profileที่ไม่ถูกต้องเพราะมันรบกวนพฤติกรรมที่คาดหวังถูกต้อง คุณคิดอย่างไรกับการจัดหา~/.bashrcจาก~/.bash_login? ในฐานะที่เป็นเชลล์ล็อกอินไม่จำเป็นต้องเป็นแบบโต้ตอบฉันเดาว่ามันไม่ถูกต้องเช่นกัน
Piotr Dobrogost

1
@PiotrDobrogost: นี่คือการสนทนาที่ยอดเยี่ยมของไฟล์เริ่มต้นเชลล์
Dennis Williamson

12

ใช้:

if tty -s; then echo interactive; fi

ดูเหมือนจะไม่ทำงาน
Steven Shaw

ดูเหมือนจะไม่เหมาะกับฉันเช่นกันฉันคิดว่านี่เป็นคำตอบที่ถูกต้อง: stackoverflow.com/a/49064632/1223975
Alexander Mills

สิ่งนี้จะตรวจสอบว่ามี TTY ในอินพุตมาตรฐานหรือไม่ แม้ว่ามันจะเกี่ยวข้องกัน แต่มันไม่เหมือนกับโหมดการโต้ตอบของเชลล์ซึ่งระบุโดยแฟล็ก "-i" ของเชลล์
yrk

ไม่ทำงาน ทำไมผู้คนถึงโหวตขึ้น?
Setop

11

testเครื่องมือที่สามารถตรวจสอบนี้ (จากหน้าคน):

 -t FD          True if FD is opened on a terminal.

ดังนั้นคุณสามารถใช้ตัวอย่างเช่น:

 if [ -t 0 ] ; then
    echo stdin is a terminal
   .....
 fi

หรือ

if [ -t 1 ] ; then
    echo stdout is a terminal
 fi

ดีและดูเหมือนว่าจะพกพาระหว่างเปลือกหอย ทดสอบbash <<< 'test -t 0 && echo Y || echo X'เขียนY, bash -c 'test -t 0 && echo Y || echo X'เขียนX
KYB

1
สิ่งนี้ยังตรวจสอบว่าอินพุตมาตรฐานคือ TTY แม้ว่ามันอาจจะเกี่ยวข้อง แต่มันไม่เหมือนกับโหมดการโต้ตอบของเชลล์ซึ่งถูกร้องขอและระบุโดยแฟล็ก "-i" ของเชลล์
yrk

6

ฉันมักจะดูผลลัพธ์ของโปรแกรม tty

หากคุณอยู่บน tty มันจะบอกคุณว่าคุณอยู่บน tty หากคุณไม่ได้อยู่ในโหมดโต้ตอบก็มักจะบอกคุณบางอย่างเช่น "ไม่ใช่ tty"


3
tty -s จะตั้งค่าส่งคืนเป็น 0 หากคุณอยู่ใน terminal หรือ 1 เป็นอย่างอื่นโดยไม่ต้องให้ผลลัพธ์ คุณสามารถใช้มันเป็น 'if tty -s; จากนั้น _ โต้ตอบ fi '
BillThor

ขอบคุณ! มันเป็นเวลานานเวลาตั้งแต่ผมต้องทำเรียงลำดับของสิ่งนี้และผมคิดว่าผมลืมรายละเอียดบางอย่าง ...
คริส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.