เชลล์แบบโต้ตอบสามารถกลายเป็นแบบไม่โต้ตอบหรือในทางกลับกันได้หรือไม่?


16

เชลล์แบบโต้ตอบสามารถกลายเป็นแบบไม่โต้ตอบหรือในทางกลับกันได้หรือไม่?

หมายเหตุ:ผมเคยทำมากของการวิจัยเกี่ยวกับคำถามพื้นฐาน "ความแตกต่างระหว่างการโต้ตอบและไม่โต้ตอบอะไร" และผลการวิจัยของฉันทำให้ฉันถามนี้คำถาม

คำถามนี้มีคำนำยาวส่วนหนึ่งเป็นเพราะมันเป็นสิ่งสำคัญสิ่งที่ประเภทของความหมายที่เราใช้สำหรับ "การโต้ตอบ" เพื่อที่จะตอบได้ คำจำกัดความอาจเป็นป้ายกำกับโดยพลการสำหรับบางชุด มันสามารถอธิบายคุณสมบัติต่าง ๆ ; หรืออาจให้ข้อมูลที่คุณสามารถใช้ในการทำนายพฤติกรรมและเข้าใจวัตถุประสงค์ ประเภทสุดท้ายนี้เราสามารถเรียกว่า "นิยามการกระทำ" หรือ "นิยามแบบไดนามิก" และเป็นประโยชน์มากที่สุด


ในman 1p shนิยามของเชลล์เชิงโต้ตอบต่อไปนี้จะได้รับ:

   If the -i option is present, or  if  there  are  no  operands  and  the
   shells  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 สร้างผลลัพธ์ที่คล้ายกันอีกครั้งยืนยันว่า$-ไม่ใช่ "แหล่งที่มาของความจริง" สำหรับการโต้ตอบของเชลล์


ดังนั้นในที่สุดคุณสมบัติของการโต้ตอบของเชลล์ที่เก็บไว้คืออะไร?

และเชลล์แบบโต้ตอบสามารถกลายเป็นแบบไม่โต้ตอบหรือในทางกลับกันได้หรือไม่? (... โดยการเปลี่ยนลักษณะนี้หรือไม่)


คำถามนี้เป็นคำถามยังกล่าวถึงการที่มีความยาวบางส่วนในการแชท
สัญลักษณ์แทน

คำตอบ:


9

คำถามที่ฉันถามจะเป็นสาเหตุที่ทุกคนต้องการทำเช่นนั้น?

คุณสามารถปิดการใช้งานบางส่วนของเชลล์เชิงโต้ตอบเช่น:

  • PS1= PS2= เพื่อปิดใช้งานพรอมต์
  • set +m เพื่อปิดการใช้งานการควบคุมงาน
  • ปิดใช้งานประวัติในบางเชลล์
  • คุณอาจจะสามารถยกเลิกการโหลดzleและโมดูลที่เสร็จสมบูรณ์ทั้งหมดzshได้

แต่ถ้าคุณต้องการให้เชลล์หยุดการโต้ตอบคุณสามารถทำได้ดังนี้:

. /some/file; exit

เพื่อบอกให้รับส่วนที่เหลือของคำสั่งจาก/some/file(แทนที่ด้วย/dev/ttyถ้าคุณยังต้องการคำสั่งที่จะอ่านจากอุปกรณ์ tty) แม้ว่าจะยังมีความแตกต่างบางอย่างจากเปลือกที่ไม่ใช่แบบโต้ตอบเช่นพฤติกรรมreturnหรือข้อเท็จจริง ว่ามันจะยังคงควบคุมงานหรือ:

exec myshell /dev/tty

หากต้องการแทนที่เชลล์เชิงโต้ตอบปัจจุบันของคุณด้วยเชลล์ที่ไม่ใช่แบบโต้ตอบที่ยังคงอ่านคำสั่งจากอุปกรณ์ tty

โปรดทราบว่าด้วย bash 4.4 set +iจะส่งคืนค่าที่bash: set: +i: invalid optionชอบในเชลล์อื่น ๆ ส่วนใหญ่


เห็นด้วยอย่างแน่นอนมันจะเป็นเรื่องไร้สาระที่จะทำ แนวคิดของฉัน "แบบโต้ตอบ" ตามที่ฉันกล่าวถึงคือมันเป็นเพียงชุดของพฤติกรรมเริ่มต้นซึ่งมีประโยชน์เมื่อคุณโต้ตอบกับเชลล์ของคุณ หากคุณสามารถเปลี่ยนพฤติกรรมเหล่านั้นทีละอย่างและคุณเปลี่ยนแต่ละอย่างได้ดังนั้นคำถาม "มันยังเป็นเชลล์เชิงโต้ตอบหรือไม่" เป็นความหมายที่ไร้สาระเพียง; มันไม่ได้เป็นคำถามสำคัญ อย่างไรก็ตาม ....
ไวด์การ์ด

1
@Wildcard หากคุณexec < <(sleep infinity)ใช้เชลล์แบบอินเทอร์แอคทีฟคุณจะมีเชลล์แบบอินเทอร์แอคทีฟที่ไม่สามารถโต้ตอบได้ เชลล์จะพิจารณาตัวเองแบบโต้ตอบในที่$-จะยังคงมีiแต่คุณอาจไม่ ฉันไม่แน่ใจว่ามีการพูดคุยเกี่ยวกับมันอีกมากมาย
Stéphane Chazelas

2
@ Wildcard หากเชลล์เริ่มต้นinteractiveมันจะยังคงอยู่ ความจริงที่ว่าคุณสามารถทำได้set +iในเวอร์ชั่นทุบตีรุ่นเก่านั้นเป็นข้อผิดพลาด
Stéphane Chazelas

1
@Wildcard ถ้าคุณดูซอร์สโค้ดของbashคุณอาจจะพบว่ามีinteractiveตัวแปรบูลทั่วโลกว่าแผนที่กับธงชาติi $-การเปลี่ยนบูลีนนั้นจะไม่เปลี่ยนพฤติกรรมทั้งหมดของเชลล์แบบโต้ตอบโดยอัตโนมัติ ไม่รองรับการเปลี่ยนจากการโต้ตอบเป็นแบบไม่โต้ตอบ
Stéphane Chazelas

4
@Wildcard Dash ยอมรับset +iและหยุดการแสดงพรอมต์ นี่เป็นสิ่งที่ผู้ใช้ไม่ควรทำดังนั้นจึงไม่น่าแปลกใจที่พฤติกรรมขึ้นอยู่กับเชลล์และมักจะเกิดอุบัติเหตุมากกว่าผลของการตัดสินใจโดยเจตนาของผู้ใช้เชลล์
Gilles 'หยุดชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.