เชลล์แบบโต้ตอบสามารถกลายเป็นแบบไม่โต้ตอบหรือในทางกลับกันได้หรือไม่?
หมายเหตุ:ผมเคยทำมากของการวิจัยเกี่ยวกับคำถามพื้นฐาน "ความแตกต่างระหว่างการโต้ตอบและไม่โต้ตอบอะไร" และผลการวิจัยของฉันทำให้ฉันถามนี้คำถาม
คำถามนี้มีคำนำยาวส่วนหนึ่งเป็นเพราะมันเป็นสิ่งสำคัญสิ่งที่ประเภทของความหมายที่เราใช้สำหรับ "การโต้ตอบ" เพื่อที่จะตอบได้ คำจำกัดความอาจเป็นป้ายกำกับโดยพลการสำหรับบางชุด มันสามารถอธิบายคุณสมบัติต่าง ๆ ; หรืออาจให้ข้อมูลที่คุณสามารถใช้ในการทำนายพฤติกรรมและเข้าใจวัตถุประสงค์ ประเภทสุดท้ายนี้เราสามารถเรียกว่า "นิยามการกระทำ" หรือ "นิยามแบบไดนามิก" และเป็นประโยชน์มากที่สุด
ในman 1p sh
นิยามของเชลล์เชิงโต้ตอบต่อไปนี้จะได้รับ:
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
จากการกล่าวถึง "-i ตัวเลือก" และการใช้คำว่า "ตัวถูกดำเนินการ" นี่หมายถึงการร้องขอของเชลล์ไม่ใช่คุณลักษณะที่สามารถตรวจสอบได้ในเชลล์ที่กำลังทำงานอยู่
หน้าคนทุบตีวลีมันแตกต่างกันเล็กน้อย:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
คำจำกัดความในประโยคแรกอีกครั้งหมายถึงการเริ่มต้นของเชลล์เท่านั้น
ประโยคที่สอง (ในการอ่านของฉัน) กำหนดเงื่อนไขที่ใช้เป็นพร็อกซีเพื่อสร้างว่าเชลล์เริ่มต้นด้วยวิธีเฉพาะที่กำหนดไว้เพื่อให้เป็น "แบบโต้ตอบ" หรือไม่
โปรดทราบว่าฉันไม่ได้ตีความประโยคนี้เป็น: "เปลือกทุบตีเป็นแบบโต้ตอบหากหาก$-
รวม 'i' เท่านั้น" $-
ดูเหมือนจะเป็นตัวบ่งชี้ที่มีประโยชน์ไม่ใช่ความหมายของการโต้ตอบ นี่เกี่ยวข้องกับคำถามของฉันอย่างมาก
ทั้งสองอย่างนี้ ( sh
คำนิยามPOSIX และของ Bash) เป็นคำจำกัดความเชิงกลที่บอกในสถานการณ์ที่ฉลาก "แบบโต้ตอบ" ใช้กับเชลล์ที่คุณเริ่ม พวกเขาไม่ใช่คำจำกัดความของการกระทำเนื่องจากไม่มีความหมายของป้ายกำกับนี้
อย่างไรก็ตามฉันเห็นว่าตลอดทั้งหน้าส่วนที่เหลือของหน้า Bash man นั้นถูกโรยการอ้างอิงถึงเชลล์ที่ทำงานในบางวิธี "ยกเว้นว่าเป็นเชลล์แบบโต้ตอบ" หรือ "เฉพาะในเชลล์แบบโต้ตอบเท่านั้นหรือตั้งค่าตัวเลือก _____" (มีตัวอย่างมากมายและนั่นไม่ใช่ประเด็นหลักของคำถามนี้)
ดังนั้นฉันจะยอมรับว่า "การโต้ตอบ" เป็นเพียงป้ายกำกับที่สะดวกสำหรับคอลเลกชันของการเริ่มต้น "การโต้ตอบ" พฤติกรรม (การตั้งค่าตัวเลือก) ที่อธิบายไว้ตลอดทั้งหน้าส่วนที่เหลือของหน้าคน มันไม่ได้เป็นคำพื้นฐานหรือวัตถุในตัวเอง มันไม่มีคำนิยามที่มีสิทธิ์นอกซอร์สโค้ดของเชลล์ (ซึ่งแตกต่างจากตัวอย่างเช่นคำว่า "open file descriptor" หรือ "กระบวนการหยุด" ซึ่งอ้างถึง abstractions ที่สร้างขึ้นในการออกแบบของเคอร์เนลเอง)
(ในขณะที่มันยังนิยามไว้ในคำนิยาม POSIX ของsh
, ว่า man page [ man 1p sh
] มีการใช้งานที่น้อยกว่ามาก "ยกเว้นว่าเชลล์เป็นแบบโต้ตอบ" และคำสั่งที่คล้ายกันกว่าที่man bash
มีและเกือบจะมุ่งเน้นเฉพาะในความแตกต่าง จากจุดนี้เป็นต้นไป)
ความหมายบางอย่างของเชลล์ที่เป็น "แบบโต้ตอบ" จะมีความเกี่ยวข้องเฉพาะในเวลาที่ร้องขอเท่านั้นเช่นไฟล์ใดที่เชลล์จะมีแหล่งที่มาก่อนที่จะอ่านคำสั่งอื่น แต่มีมีผลกระทบ (อย่างน้อยในทุบตี) ที่มีความเกี่ยวข้องในเวลาใดก็ได้ ดังนั้นจึงต้องมีวิธีที่จะบอกสำหรับการใด ๆ ที่ได้รับการเรียกใช้เปลือกไม่ว่าจะเป็นแบบโต้ตอบหรือไม่
เล่นset +i
ในการโต้ตอบเปลือกทุบตีทำให้ 'i' $-
จะถูกลบออกจากเนื้อหาของ
คำถามคือ: สิ่งนี้จริง ๆ แล้วหมายความว่าเปลือกไม่โต้ตอบอีกต่อไป?
ตามคำนิยามที่แน่นอนทุบตีก็ไม่ควรตั้งแต่ไม่มีที่ไหนในความหมายของมันคือต้องว่า 'I' จะอยู่ใน$-
:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
การอ่านคำจำกัดความที่ถูกต้องทำให้เกิดคำถามที่เข้มงวดเช่นกัน: หาก stdin หรือ stderr ของเทอร์มินัลแบบโต้ตอบถูกเปลี่ยนเส้นทางดังนั้นพวกมันจึงไม่ได้เชื่อมต่อกับเทอร์มินัลอีกต่อไป
( ปรากฏว่าคำตอบสำหรับคำตอบนี้คือ "ไม่" และหน้า man อาจรวมถึงโมดิฟายเออร์: "ซึ่งทั้งอินพุตและข้อผิดพลาดมาตรฐานเชื่อมต่อกับเทอร์มินัล ... ในเวลาที่ร้องขอ " แต่ฉันไม่รู้ แตกหัก.)
ถ้าคำตอบคือ "ไม่มีเปลือกไม่สามารถกลายเป็นไม่โต้ตอบหรือในทางกลับกัน" แล้วสิ่งที่เป็นที่ชัดเจนวิธีการตรวจสอบถ้าเปลือกเป็นแบบโต้ตอบ?
ใส่อีกวิธีหนึ่ง: หากมีพฤติกรรมของ "เชลล์แบบโต้ตอบ" ซึ่งยังคงมีอยู่หลังจากset +i
นั้นสิ่งที่ใช้ในการพิจารณาว่าพฤติกรรมเหล่านั้นควรดำเนินการต่อไปอย่างไร
เกรงว่าทุกคนต้องสงสัยเลยว่ามันมีเป็นพฤติกรรมของเปลือกโต้ตอบซึ่งยังคงมีอยู่หลังจากที่เรียกและพฤติกรรมของเปลือกเรียกไม่ใช่โต้ตอบซึ่งยังคงมีอยู่หลังset +i
set -i
ตัวอย่างเช่นพิจารณาข้อความที่ตัดตอนมาจากman bash
:
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
ดังนั้นโดยการตั้งค่าinteractive_comments
ตัวเลือกเราสามารถเห็นความแตกต่างระหว่างเชลล์แบบโต้ตอบและแบบไม่โต้ตอบ การคงอยู่ของความแตกต่างนี้แสดงให้เห็นโดยสคริปต์ต่อไปนี้:
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
สิ่งนี้เป็นการยืนยันว่า "การโต้ตอบ" และ "มีi
ค่า$-
" ไม่เทียบเท่า
การทดสอบที่คล้ายกันโดยใช้${parameter:?word}
กับพารามิเตอร์ unset สร้างผลลัพธ์ที่คล้ายกันอีกครั้งยืนยันว่า$-
ไม่ใช่ "แหล่งที่มาของความจริง" สำหรับการโต้ตอบของเชลล์
ดังนั้นในที่สุดคุณสมบัติของการโต้ตอบของเชลล์ที่เก็บไว้คืออะไร?
และเชลล์แบบโต้ตอบสามารถกลายเป็นแบบไม่โต้ตอบหรือในทางกลับกันได้หรือไม่? (... โดยการเปลี่ยนลักษณะนี้หรือไม่)