มันขึ้นอยู่กับเปลือกหอยเป็นอย่างมาก ตรวจสอบคู่มือเชลล์ของคุณสำหรับรายละเอียด
โปรดทราบว่าอักขระบางตัวมีความพิเศษเฉพาะในบริบทบางอย่าง ยกตัวอย่างเช่นในเปลือกหอยมากที่สุด*
และ?
เป็นเพียงพิเศษในบริบทรายการใน POSIX หรือ csh เหมือนเปลือกหอยเป็นพิเศษเพียงจุดเริ่มต้นของคำต่อไปนี้หรือตัวอักษรบางอย่างเช่น~
:
เดียวกันใน=
zsh
ในเปลือกบาง[
เป็นพิเศษเฉพาะเมื่อจับคู่ (ที่มีข้อ จำกัด บางอย่าง) ]
โดย
ในบางเชลล์เช่นbash
หรือyash
อักขระพิเศษเช่นตัวคั่นโทเค็นว่างยังแตกต่างกันตามโลแคล
ตัวดำเนินการข้อความ (เพื่อลบความหมายพิเศษของตัวละครเหล่านั้น) ยังแตกต่างกันอย่างมากระหว่างเชลล์
กระสุนคล้ายบอร์น
ข้อมูลสรุปสำหรับเชลล์คล้าย Bourne (นั่นคือเชลล์ที่รู้จักกันว่าถูกเรียกใช้sh
บนระบบบางระบบหรือตั้งแต่ปี 80):
เชลล์เป้าหมาย
ตัวละครพิเศษ:
"\'&|;()^`<>$
พื้นที่ช่องว่างขึ้นบรรทัดใหม่และแท็บเป็นพิเศษในบรรทัดคำสั่งง่าย ๆ เมื่อไม่ยกมา
#
(ยกเว้นในรุ่นแรก) เป็นพิเศษที่จุดเริ่มต้นของบรรทัดต่อไปนี้หรือพื้นที่ unquoted &|()^<>;`
แท็บหรือ
{
และ}
มีความพิเศษเฉพาะในสิ่งที่พวกเขาเป็นคำหลักเปลือก (เฉพาะคำที่อยู่ในตำแหน่งคำสั่ง)
*?[
เป็นพิเศษในฐานะผู้ประกอบการแบบกลมดังนั้นเฉพาะในบริบทรายการ ในกรณีของ[
มัน[...]
ที่เป็นผู้ประกอบการ globbing อย่างใดอย่างหนึ่ง[
หรือ]
ต้องการเพียงที่จะยกมาเพื่อลบความหมายพิเศษ
=
เป็นพิเศษเมื่ออยู่ในบริบทที่ถือว่าเป็นผู้ดำเนินการที่ได้รับมอบหมาย นั่นคือในคำสั่งง่าย ๆ สำหรับทุกคำที่ไม่ทำตามอาร์กิวเมนต์ (ยกเว้นหลังจากset -k
)
การอ้างอิงตัวดำเนินการ
\
อัญประกาศอักขระพิเศษทั้งหมดยกเว้นการขึ้นบรรทัดใหม่ ( \<newline>
เป็นวิธีการต่อสายตรรกะยาวไปยังบรรทัดทางกายภาพถัดไปดังนั้นลำดับนั้นจะถูกเอาออก) โปรดทราบว่า backticks จะเพิ่มความซับซ้อนเป็นพิเศษภายในนั้น\
ถูกใช้ก่อนเพื่อหลีกเลี่ยง backtick ที่ปิดและช่วยให้โปรแกรมแยกวิเคราะห์ ภายในราคาคู่\
อาจจะใช้เพียงที่จะหลบหนีตัวเอง"
, $
และ`
( \<newline>
ยังคงเป็นต่อของบรรทัด) "
ภายในที่นี่เอกสารเดียวกันยกเว้น \
เป็นวิธีเดียวในการหลบหนีอักขระที่อยู่ภายในเอกสาร
"..."
ราคาสองตัวหนี แต่ตัวเอง\
, และ$
`
'...'
อัญประกาศเดี่ยวยกเว้นอักขระทั้งหมดยกเว้นตัวของมันเอง
เปลือกหอย POSIX
POSIX เชลล์ส่วนใหญ่จะทำงานเหมือนกับเชลล์เป้าหมายยกเว้นว่า:
^
ไม่มีตัวอักษรพิเศษอีกต่อไป
~
มีความพิเศษในบางบริบท
{
ได้รับอนุญาตให้เป็นพิเศษดังนั้นควรจะยกมา
ksh
ชอบ POSIX ยกเว้นว่า:
{string}
เป็นพิเศษถ้าสตริงมี unquote ,
(หรือ..
ในบางกรณีและบางรุ่น)
- ksh93 มีตัวดำเนินการข้อความพิเศษเพิ่มเติม:
$'...'
พร้อมกฎที่ซับซ้อน ผู้ประกอบการที่ยังพบ (ด้วยรูปแบบบาง) ในbash
, zsh
, mksh
และ FreeBSD และ sh
busybox
ksh93
นอกจากนี้ยังมีตัว$"..."
ดำเนินการข้อความที่ทำงานเหมือน"..."
ยกเว้นว่าสตริงนั้นขึ้นอยู่กับการแปล (สามารถกำหนดค่าได้ดังนั้นจึงแปลเป็นภาษาของผู้ใช้) mksh
ไม่สนใจใน$
$"..."
bash
ชอบksh93
แต่:
- ในโลแคลอักขระไบต์เดียวอักขระว่าง (ตามโลแคล) ทั้งหมดถือว่าเป็นตัวคั่น (เช่นเว้นวรรคหรือแท็บ) นั่นหมายความว่าคุณควรอ้างอิงไบต์ทั้งหมดด้วยชุดที่ 8 ในกรณีที่พวกเขาอาจเป็นอักขระว่างในบางภาษา
- เมื่อเปิดใช้งานการขยายประวัติ csh เหมือนในอินสแตนซ์แบบอินเทอร์แอคทีฟ
!
เป็นพิเศษในบางบริบท และ^
เป็นพิเศษที่จุดเริ่มต้นของคำสั่ง
zsh
ชอบksh93
แต่:
- เช่นเดียวกับสำหรับ
bash
การขยายประวัติ csh
=
มีความพิเศษเป็นอักขระตัวแรกของคำ ( =ls
ขยายเป็น/bin/ls
)
{
และ}
ยังสามารถเปิดและปิดกลุ่มคำสั่งเมื่อไม่ได้คั่นด้วย (ในการ{echo text}
ทำงานเหมือนของ Bourne { echo text;}
)
- ยกเว้น
[
เพียงอย่างเดียวความต้องการที่ยกมาแม้ว่าจะไม่ได้ปิดด้วย[
]
- ด้วย
extendedglob
ตัวเลือกที่เปิดใช้งาน#
, ^
และ~
จะ globbing ผู้ประกอบการ
- ด้วย
braceccl
ตัวเลือก{non-empty-string}
เป็นพิเศษ
$"..."
ไม่รองรับ
- เป็นมุมแหลมพิเศษ
?
ไม่พิเศษเมื่อทำตาม%
(แม้จะยกมาหรือขยาย) ที่จุดเริ่มต้นของคำ (เพื่อให้สเปค%?name
งาน)
rcquotes
ตัวเลือก (ไม่ได้เปิดใช้งานโดยค่าเริ่มต้น) ช่วยให้หนึ่งเพื่อใส่คำพูดเดียว''
ราคาเดียวภายในàลาrc
(ดูด้านล่าง)
yash
ชอบPOSIX
ยกเว้นว่า
- อักขระว่างทั้งหมดถือเป็นตัวคั่น
- ด้วย
brace-expand
ตัวเลือกนี้จะใช้การขยายปีกกาแบบ zsh
สำหรับเชลล์ทั้งหมดมีบริบทพิเศษบางอย่างที่การอ้างอิงทำงานแตกต่างกัน เราได้กล่าวแล้วที่นี่เอกสารและ backticks แต่ยังมี[[...]]
ใน ksh และไม่กี่เปลือกหอยอื่น ๆ POSIX $((...))
, case
โครงสร้าง ...
นอกจากนี้โปรดทราบว่าการอ้างถึงสามารถมีผลข้างเคียงอื่น ๆ เมื่อกล่าวถึงการขยาย (พร้อมเครื่องหมายคำพูดคู่) หรือเมื่อใช้กับตัวคั่นเอกสารที่นี่ นอกจากนี้ยังปิดใช้งานคำที่สงวนไว้และมีผลกับการขยายชื่อแทน
สรุป
ในเชลล์คล้ายบอร์น!#$^&*?[(){}<>~;'"`\|=
, SPC, TAB, NEWLINE และบางไบต์ที่มีชุดบิตที่ 8 เป็นหรืออาจเป็นพิเศษ (อย่างน้อยในบางบริบท)
ในการลบความหมายพิเศษเพื่อให้ได้รับการปฏิบัติอย่างแท้จริงคุณใช้ข้อความ
ใช้:
'...'
เพื่อลบความหมายพิเศษของตัวละครทุกตัว:
printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
single arguments (without the enclosing quotes) to `printf`'
\
เพื่อลบความหมายพิเศษของอักขระหนึ่งตัวเท่านั้น:
printf '<%s>\n' foo bar\ baz #comment
ข้างต้นเท่านั้นอักขระช่องว่างนำโดยถูกส่งผ่านไปยังตัวอักษร\
printf
อีกอันหนึ่งถือว่าเชลล์เป็นตัวคั่นโทเค็น
- ใช้
"..."
ในการอ้างอิงตัวละครในขณะที่ยังช่วยให้การขยายตัวพารามิเตอร์ ( $var
, $#
, ${foo#bar}
... ), การขยายตัวทางคณิตศาสตร์ ( $((1+1))
ยัง$[1+1]
อยู่ในเปลือกหอยบางส่วน) และคำสั่งเปลี่ยนตัว ( $(...)
หรือรูปแบบเก่า`...`
. จริงส่วนใหญ่ของเวลาที่คุณไม่ต้องการที่จะนำการขยายภายในเหล่านั้น อัญประกาศคู่ในกรณีใด ๆคุณสามารถใช้\
ภายใน"..."
เพื่อลบความหมายพิเศษของตัวละครที่ยังคงพิเศษ (แต่พวกเขาเท่านั้น)
ถ้าสตริงมี'
อักขระ, คุณยังสามารถใช้'...'
สำหรับส่วนที่เหลือและใช้กลไกข้อความอื่น ๆ ที่สามารถพูด'
เหมือน"'"
หรือ\'
หรือ (ถ้ามี) $'\''
:
echo 'This is "tricky", isn'\''t it?'
ใช้$(...)
รูปแบบที่ทันสมัยของการทดแทนคำสั่ง ใช้ของเก่าเท่านั้น`...`
สำหรับความเข้ากันได้กับเชลล์เป้าหมายนั่นคือระบบเก่ามากและเฉพาะในการกำหนดตัวแปรตามที่ไม่ได้ใช้:
echo "`echo "foo bar"`"
ซึ่งจะไม่ทำงานกับ Bourne shell หรือ AT&T เวอร์ชัน ksh หรือ:
echo "`echo \"foo bar\"`"
ซึ่งจะทำงานกับ Bourne และ AT&T ksh แต่ไม่ใช่ด้วยyash
แต่ใช้:
var=`echo "foo bar"`; echo "$var"
ซึ่งจะทำงานกับทั้งหมด
การวางซ้อนคำหลักด้วยเครื่องหมายคำพูดคู่นั้นเป็นไปไม่ได้ดังนั้นให้ใช้ตัวแปรอีกครั้ง ระวังการประมวลผลแบ็กสแลชพิเศษด้วย:
var=`printf '%s\n' '\\'`
จะเก็บเครื่องหมายแบ็กสแลชหนึ่งอันไว้ข้างใน$var
เท่านั้นเนื่องจากมีการประมวลผลแบ็กสแลชในระดับพิเศษ (สำหรับ\
, `, และ$
(และ"
เมื่ออ้างถึงยกเว้นในyash
)) ภายในแบ็คทีกเกอร์ดังนั้นคุณจึงต้องการ
var=`printf '%s\n' '\\\\'`
หรือ
var=`printf '%s\n' '\\\'
แทน.
ครอบครัว Csh
csh และ tcsh มีรูปแบบที่แตกต่างกันอย่างมีนัยสำคัญแม้ว่าจะยังมีจำนวนมากที่เหมือนกันกับเชลล์เป้าหมายในขณะที่พวกเขาแบ่งปันมรดกร่วมกัน
ตัวละครพิเศษ:
"\'&|;()^`<>$
พื้นที่ช่องว่างขึ้นบรรทัดใหม่และแท็บพิเศษทุกที่เมื่อไม่มีการเสนอราคา
#
(csh เป็นเชลล์ที่นำเสนอ#
ในฐานะผู้นำความคิดเห็น) เป็นพิเศษที่จุดเริ่มต้นของสคริปต์หรือทำตามช่องว่างแท็บหรือการขึ้นบรรทัดใหม่
*?[
มีความพิเศษเหมือนโอเปอเรเตอร์ globbing ดังนั้นในบริบทรายการ
{non-empty-string}
เป็นพิเศษ (csh คือเชลล์ที่แนะนำการขยายรั้ง)
!
และ^
พิเศษเป็นส่วนหนึ่งของการขยายประวัติ (อีกครั้งการประดิษฐ์ csh) และกฎการอ้างถึงเป็นพิเศษ
~
(การขยายตัวหนอนยังเป็นสิ่งประดิษฐ์ csh) เป็นพิเศษในบริบทบางอย่าง
การอ้างอิงตัวดำเนินการ
พวกมันเหมือนกับเชลล์เป้าหมาย แต่พฤติกรรมนั้นแตกต่างกัน tcsh ทำงานเหมือน csh จากมุมมองไวยากรณ์คุณจะพบว่า csh หลายเวอร์ชันมีข้อบกพร่องที่น่ารังเกียจ รับ tcsh รุ่นล่าสุดเพื่อรับ csh เวอร์ชันที่ใช้งานได้ประมาณ
\
ยกเว้นอักขระเดี่ยวยกเว้นขึ้นบรรทัดใหม่ (เหมือนกับเชลล์เป้าหมาย) มันเป็นโอเปอเรเตอร์ตัวเดียวที่สามารถหลบหนี!
ได้ \<newline>
ไม่ได้หลบหนี แต่เปลี่ยนจากตัวแยกคำสั่งเป็นตัวแยกโทเค็น (เช่นช่องว่าง)
"..."
หนีออกมาตัวละครทุกตัวยกเว้นตัวเอง$
, `
, !
บรรทัดใหม่ ตรงกันข้ามกับ Bourne shell คุณไม่สามารถใช้\
เพื่อหลบหนี$
และ`
เข้าด้านใน"..."
แต่คุณสามารถใช้\
เพื่อหลบหนี!
หรือขึ้นบรรทัดใหม่ (แต่ไม่ใช่ตัวเองยกเว้นเมื่อก่อนหน้า!
หรือขึ้นบรรทัดใหม่) ตัวอักษร!
มี"\!"
และตัวอักษรมี\!
"\\!"
'...'
หนีอักขระทั้งหมดยกเว้นตัวเอง!
และขึ้นบรรทัดใหม่ เช่นเดียวกับเครื่องหมายคำพูดคู่!
และขึ้นบรรทัดใหม่สามารถหนีด้วยแบ็กสแลช
- การทดแทนคำสั่งเป็นเพียงผ่านทาง
`...`
ไวยากรณ์และแทบจะไม่สามารถใช้งานได้อย่างน่าเชื่อถือ
- การทดแทนตัวแปรนั้นค่อนข้างออกแบบมาไม่ดีและเกิดข้อผิดพลาดได้ง่าย
$var:q
ผู้ประกอบการจะช่วยให้การเขียนรหัสตัวแปรที่เกี่ยวข้องกับความน่าเชื่อถือมากขึ้น
สรุป
อยู่ห่างจาก csh ถ้าคุณทำได้ หากคุณไม่สามารถใช้:
- อัญประกาศเดี่ยวเพื่ออ้างอิงอักขระส่วนใหญ่ และการขึ้นบรรทัดใหม่ยังคงต้อง
!
\
\
สามารถหลบหนีตัวละครส่วนใหญ่
"..."
สามารถอนุญาตให้มีการขยายภายในบางส่วนได้ แต่นั่นก็ค่อนข้างบั๊กถ้าพวกเขาฝังอักขระขึ้นบรรทัดใหม่และ / หรือเครื่องหมายแบ็กสแลชสิ่งที่ดีที่สุดคือการใช้เครื่องหมายคำพูดเดี่ยวเท่านั้นและ$var:q
สำหรับการขยายตัวแปร คุณจะต้องใช้ลูปถ้าคุณต้องการเข้าร่วมองค์ประกอบของอาร์เรย์ที่เชื่อถือได้
rc
ครอบครัว
rc
เป็นplan9
เปลือกและชอบลูกหลานของมันes
และakanga
ได้รับการ ported เพื่อ Unix และชอบ Unix นั่นคือเชลล์ที่มีรูปแบบที่สะอาดและดีกว่าและคนที่ทุกคนจะใช้ถ้าเราไม่ได้ติดอยู่กับเชลล์ที่มีลักษณะคล้ายบอร์นเพื่อการทำงานร่วมกันแบบย้อนหลัง
rc
/akanga
ตัวละครพิเศษ
#;&|^$=`'{}()<>
, SPC, TAB และ NEWLINE จะพิเศษเสมอเมื่อไม่มีการเสนอราคา
*?[
เป็นผู้ประกอบการ globbing
ตัวดำเนินการการอ้างอิง
'...'
เป็นโอเปอเรเตอร์ตัวเดียว ครอกที่'
เขียนด้วย''
คำพูดเดียวใน:
echo 'it''s so simple isn''t it?'
es
es
อาจจะเห็นเป็นทดลองrc
เปลือกขึ้นอยู่กับ
มันมีความแตกต่างเล็กน้อย หนึ่งในสิ่งที่น่าสนใจสำหรับ Q / A นี้ก็\
คือตัวดำเนินการที่อ้างถึง (ที่พูดถึงอักขระพิเศษทั้งหมดยกเว้นการขึ้นบรรทัดใหม่) และยังสามารถใช้เพื่อแนะนำลำดับ escape เช่น\n
สำหรับการขึ้นบรรทัดใหม่\b
สำหรับแบ็กสแลช ...
ปลา
ปลาเป็นผู้ใช้ใหม่ที่สัมพัทธ์ (ประมาณปี 2005) มีวัตถุประสงค์หลักสำหรับการใช้งานแบบโต้ตอบและยังมีไวยากรณ์ที่แตกต่างกันอย่างมีนัยสำคัญจากเปลือกหอยอื่น ๆ
ตัวอักษรพิเศษ
"'\()$%{}^<>;&|
พิเศษเสมอเมื่อไม่ยกมา (หมายเหตุ%
(สำหรับการขยาย pid) เป็นความแตกต่างอย่างมีนัยสำคัญจากกระสุนอื่น ๆ และ`
ไม่พิเศษ)
#
(ความคิดเห็น) พิเศษเมื่อติดตามช่องว่างแท็บขึ้นบรรทัดใหม่หรือ ;&|^<>
*?
(แต่ไม่ใช่[...]
) ตัวดำเนินการแบบกลม
การอ้างอิงตัวดำเนินการ
\
อัญประกาศอักขระพิเศษเดียวยกเว้นการขึ้นบรรทัดใหม่ แต่ระวังว่ามันจะเพิ่มเป็นคู่ตามลำดับตัวหลีกเลี่ยง C ( \n
, \b
... ) IOW \n
ไม่ได้อ้างถึงn
แต่ขึ้นบรรทัดใหม่
"..."
อัญประกาศทุกอย่าง แต่ตัวของมันเอง$
และแบ็กสแลชและแบ็กสแลชสามารถใช้เพื่อหลบหนีสิ่งเหล่านั้น \<newline>
เป็นความต่อเนื่องสาย (ออก) "..."
ภายใน
'...'
พูดทุกอย่างยกเว้นตัวเองและ\
และคุณสามารถใช้แบ็กสแลชเพื่อหลบหนีสิ่งเหล่านั้น
=
,@
และ%
เป็นพิเศษในเปลือกหอยบางอย่างในบางบริบท