เทอร์มินัลเข้าสู่โหมดใดเมื่อฉันพิมพ์เครื่องหมายคำพูดเดี่ยว?


11

เมื่อฉันป้อนเครื่องหมายคำพูดเดี่ยว'ในเทอร์มินัลมันจะไปยังโหมดอื่นและคำสั่งจะไม่ทำงาน โหมดนี้คืออะไรและเมื่อไหร่ที่เราจะใช้มัน?

root@sai:~# '
> ls
> '
ls
: command not found
root@sai:~#

30
และทำไมคุณถึงทำงานเหมือนรูท?
Zanna

13
เทอร์มินัลของคุณอยู่ในโหมดเดียวกับก่อนหน้านี้ - เชลล์ของคุณอยู่ในโหมดที่แตกต่างกัน (กำลังรอความสมบูรณ์ของสตริงด้วย')
ohno

คำตอบ:


26

อย่างมีประสิทธิภาพเชลล์ขอคำสั่ง / นิพจน์ที่สมบูรณ์และด้วยเหตุผลดังกล่าวจึงแสดงPS2สตริงพรอมต์

จากman bash:

กระตุ้น

เมื่อดำเนินการแบบโต้ตอบ bash จะแสดง PS1 พร้อมท์หลักเมื่อพร้อมที่จะอ่านคำสั่งและPS2 ที่สองจะพร้อมรับคำสั่ง เมื่อจำเป็นต้องมีอินพุตมากขึ้นเพื่อทำคำสั่งให้สมบูรณ์

และก่อนหน้านั้นเล็กน้อย:

  PS2    The value of this parameter is  expanded
          as  with  PS1  and used as the secondary
          prompt string.  The default is ``> ''.

ดังนั้นอย่างที่คุณคาดเดาจากการอ่านเอกสารเชลล์มีหลายคำสั่งพร้อมจุดประสงค์ที่แตกต่างกัน PS1พรอมต์ของคุณเป็นroot@sai:~#สตริงซึ่งแสดงให้เห็นถึงตามปกติเมื่อคุณป้อนคำสั่ง >เป็นPS2พรอมต์ มีอื่น ๆ เช่นกัน: PS3สำหรับselectบล็อกคำสั่งและPS4สำหรับการดีบักด้วยset -xคำสั่ง PS2ในกรณีนี้เรากำลังให้ความสนใจใน

มีหลายวิธีที่เชลล์อาจแสดงPS2พรอมต์ (และตำแหน่งที่คำสั่งบนบรรทัดใหม่อาจจำเป็น) พรอมต์เดียวกันจะใช้เมื่อคุณทำการhere-docเปลี่ยนเส้นทาง (โดยที่คำสั่งนั้นถือว่าเสร็จสมบูรณ์เมื่อคุณเห็นสตริงที่สิ้นสุดในตัวอย่างนี้EOF):

$ cat <<EOF
> line one
> line two
> EOF
line one
line two

บ่อยครั้งที่ความต่อเนื่องของคำสั่งที่มีความยาวสามารถทำได้โดยการเพิ่ม\และขึ้นบรรทัดใหม่ (!) ทันทีซึ่งจะทำให้พรอมต์เดียวกันปรากฏขึ้น:

$ echo Hello\
> World
HelloWorld

$ echo 'Hello\                                                                                                           
> World'
Hello\
World

เมื่อไพพ์ตัวดำเนินการเชิงตรรกะหรือคำสำคัญพิเศษปรากฏบนบรรทัดคำสั่งก่อนขึ้นบรรทัดใหม่คำสั่งนั้นจะถือว่าไม่สมบูรณ์จนกว่าจะป้อนคำสั่งสุดท้ายทั้งหมด:

$ echo Hello World | 
> wc -l
1

$ echo Hello World &&                                                                                                    
> echo "!"
Hello World
!

$ for i in $(seq 1 3); do
> echo "$i"
> done
1
2
3 

$ if [ -f /etc/passwd ]
> then
>     echo "YES"
> fi
YES

ในกรณีของคุณคำพูดเดี่ยวหมายถึงการตีความตามตัวอักษรของสิ่งที่อยู่ระหว่างคำพูดเดียว ดังนั้นดังที่ Zanna ชี้ให้เห็นคุณกำลังป้อนคำสั่งที่ประกอบด้วย newline + ls+ newline ไม่สามารถค้นหาชื่อไฟล์ที่เรียกใช้งานได้ (และโดยทั่วไปชื่อไฟล์คำสั่งควรประกอบด้วยอักขระที่เป็นตัวอักษรและตัวเลขรวมถึงเครื่องหมายขีดล่างเครื่องหมายขีดกลางและจุด) แม้ว่าจะเป็นไปได้จริง ๆ ที่จะมีชื่อไฟล์ที่มีอักขระพิเศษอยู่ในนั้น แต่ก็สามารถหลีกเลี่ยงได้เสมอ

หมายเหตุ : พฤติกรรมดังกล่าวตามที่แสดงในตัวอย่างของคุณเป็นเฉพาะกับบอร์นเหมือนเปลือกหอยรวมทั้งbash, dash(บน Ubuntu มันเป็น symlinked ไป/bin/sh) และksh และอนุพันธ์ของมันไม่ทำงานในลักษณะนี้:mkshcsh

$ tcsh                                                    
eagle:~> '
Unmatched '.
eagle:~> csh
% '
Unmatched '.
%  

อย่างไรก็ตามในโหมดการโต้ตอบcshจะยังคงเพิ่ม?เป็นพรอมต์ 2เมื่อต้องการข้อมูลเพิ่มเติม:

$ csh
% foreach n ( 1 2 3 )
? echo $n
? end
1
2
3  

ดูสิ่งนี้ด้วย:


ลิงก์What's the difference between <<, <<< and < < in bash?ออฟไลน์ / ผิด
Tico

@ ติโกขอบคุณคงที่ คำตอบนั้นเขียนด้วยความเร็วอินเทอร์เน็ตของเต่าพันล้านต่อวินาทีซึ่งส่งผลให้มีการเชื่อมโยงคัดลอกเพียงบางส่วนเท่านั้น แก้ไขแล้ว
Sergiy Kolodyazhnyy

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

30

เปลือกกำลังรอใบเสนอราคาปิด เมื่อคุณป้อนมันจะทำสิ่งที่มันมักจะทำและพยายามที่จะดำเนินการคำสั่งที่ป้อน

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

เนื่องจากไม่มีคำสั่งเช่น<newline>ls<newline>นั้นจึงไม่พบ

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