คำสั่ง "อัญประกาศ" ในเชลล์


15

การใช้คำสั่งquoteคืออะไร? ฉันไม่พบข้อมูลใด ๆ เกี่ยวกับมันไม่ใช่ไฟล์ปฏิบัติการใน/binโฟลเดอร์และไม่พบใน Bash ในตัว ดูเหมือนว่ามันจะพิมพ์พารามิเตอร์แรกเท่านั้นเช่นechoคำสั่งและไม่มีอะไรเพิ่มเติม


มันเพิ่งเพิ่มเครื่องหมายคำพูด
Hakeem Wahab

1
เพียงโผล่ไปรอบ ๆ ฉันพบโปรแกรมอรรถประโยชน์ที่เรียกว่า shell-quote ซึ่งคล้ายกับ quote แต่มีประโยชน์บางอย่างกับสิ่งต่าง ๆ เช่น ssh และสำหรับการดีบักสคริปต์ทุบตี คิดว่าฉันจะใส่ไว้ที่นี่เป็นเชิงอรรถ ' linux.die.net/man/1/shell-quote '
Joe

รู้สึกเหมือน WTF มีคำทั่วไปquoteใช้เพื่อวัตถุประสงค์ที่คลุมเครือ ... ไม่มีคำนำหน้าให้ทำเครื่องหมายว่า "ภายใน" ไม่มีเอกสารไม่มีอะไรนอกจากคุณจะขุดในรายละเอียดการใช้งานกลไกการเสร็จสิ้นขั้นสูงของ distro ฉันคิดว่ามันน่ารำคาญนิดหน่อย
hyde

มันจะคลุมเครือมากขึ้นสำหรับบุคคลที่ภาษาแม่ไม่ใช่ภาษาอังกฤษ เช่นฉันเช่น :)
whtyger

คำตอบ:


10

มันคืออะไร?

ฉันสังเกตเห็นว่าคำสั่งนี้ไม่ทำงานในเปลือกของฉัน ( ปลาเปลือกโต้ตอบที่เป็นมิตร ) ดูเหมือนว่าจะใช้งานได้เฉพาะกับทุบตีเท่านั้น (ค่าเริ่มต้นของ Ubuntu)

chocobai@pc ~> /bin/bash 
chocobai@pc:~$ quote asdf
'asdf'chocobai@pc:~$ 

chocobai@pc:~$ type quote
quote is a function.
quote ()
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

มันทำอะไร? มันใช้ทำอะไรได้บ้าง?

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

มันแปลกจริง ๆ ฉันไม่พบเอกสารใด ๆ (ในเว็บ) เกี่ยวกับมัน แต่ก็ง่ายที่จะเห็นว่ามันทำอะไร


2
whichไม่มีประโยชน์ทั้งในเชลล์แบบโต้ตอบและในสคริปต์ ใช้typeแทน type quoteจะบอกคุณว่ามันเป็นฟังก์ชั่นและแม้กระทั่งแสดงความหมายของฟังก์ชั่น เรียกใช้help typeเพิ่มเติมเกี่ยวกับtypebuiltin
geirha

คุณพูดถูกขอบคุณ ฉันเห็นคำตอบข้างต้นซึ่งใช้ประเภทเพื่อค้นหาว่ามันคืออะไร ขอบคุณด้วย 'ซึ่ง' ฉันรู้ว่ามันไม่ใช่ไฟล์ที่ปฏิบัติการได้ใน / bin / หรือมากกว่านั้นเพราะมันไม่ได้กลับเส้นทางใด ๆ ฉันคิดว่ามันยังคงมีประโยชน์ แต่คุณพูดถูกฉันจะเพิ่มประเภท
verpfeilt

2
ในอูบุนตูของฉัน 12.04 ฟังก์ชั่นนี้มีการอธิบายจริงๆ/etc/bash_completionซึ่งเป็นแหล่งที่มา~/.bashrcโดยค่าเริ่มต้นไม่ใช่โดย/etc/bash.bashrcที่ส่วนที่เกี่ยวข้องกับการ/etc/bash_completionแสดงความคิดเห็น นอกจากนี้/usr/share/bash-completion/โฟลเดอร์จะหายไปใน Ubuntu 12.04
whtyger

8

quoteเป็นฟังก์ชั่นที่กำหนดไว้ (ที่นี่ในระบบ Debian ของฉัน แต่ฉันคิดว่ามันเหมือนกันบน Ubuntu) ในไฟล์/usr/share/bash-completion/bash_completionซึ่งตัวมันเองมีต้นกำเนิดมาจาก/etc/bash.bashrcตอนเริ่มต้นของ Bash

ฉันจะไม่ใช้ฟังก์ชั่นนี้! หากคุณต้องการเสนอราคาเพื่อให้เชลล์ใช้งานได้อย่างปลอดภัยโปรดใช้printfกับโมดิ%qฟายเออร์เป็น:

printf '%q\n' "Hello my friend I like 'single quotes' as well as \"double quotes\""

ในความเป็นจริงแม้จะใช้น้อยมาก แต่ก็มีกลยุทธ์ที่ดีกว่าสำหรับสิ่งระดับสูงเช่นเราผู้ใช้มักจะทำ quoteสิ่งนี้ถูกใช้ภายในโดยสิ่งที่คลุมเครือบางอย่างที่เราไม่ต้องการแม้แต่จะรู้ นี้quoteฟังก์ชั่นน่าจะเป็นผู้ผลิต / จัดจำหน่ายเฉพาะ (อ่าน Debian เฉพาะ) และอาจจะไม่ได้เป็นแบบพกพาที่ทั้งหมดและก็อาจจะมีการเปลี่ยนแปลงในอนาคต

แก้ไข ผมได้ตรวจสอบเพียงแค่บน Ubuntu 12.04 ระบบและquoteฟังก์ชั่นที่กำหนดไว้ใน/etc/bash_completionที่มาจากตัวเองมาโดย/etc/bash.bashrc/etc/profile

ฉันทราบได้อย่างไร ใช้ฮิวริสติกเล็กน้อย:

  • ตรวจสอบว่าquoteปรากฏใน/etc/profile:

    grep '\bquote\b' /etc/profile

    ไม่ไปยังขั้นตอนต่อไป

  • ไฟล์อะไรที่มาจาก/etc/profile?

    grep '[[:space:]]\.[[:space:]]' /etc/profile

    ฉันมี$i(ต้องมองเข้าไปในแหล่งที่มาสำหรับสิ่งที่มานี้ แต่ในกรณีนี้มันเป็นไฟล์/etc/profile.d/*.shถ้ามี (และถ้าอ่านได้) และ/etc/bash.bashrc. กำลังมองหา/etc/bash.bashrc.

  • อยู่quoteใน/etc/bash.bashrc? ใช่ / ไม่ ฯลฯ

quoteไม่หนีคำพูดเดียวดังนั้นจึงสามารถใช้งานได้โดยเปลือก มันทำงานได้ดีเช่นเดียวกับprintf %qกรณีการใช้งานนี้
Flimm

@Flimm ใช้ความเสี่ยงของคุณเอง!
gniourf_gniourf

@gniourf_gniourf ฉันคิดว่าprintf% qจัดการ tilde ไม่ได้ ( ~ ) my_str='~/.bashrc'; echo ' Expected:' "$my_str"; bash -c "echo ' quote:' $(quote "$my_str")"; bash -c "echo 'printf %q:' $(printf '%q\n' "$my_str")"ลองนี้: คุณจะเห็นสิ่งที่ชอบExpected: ~/.bashrc, และquote: ~/.bashrc printf %q: /home/your_username/.bashrc
Rockallite

1
@ Rockallite: ฉันเพิ่งลองและใช้งานได้ตามที่คาดไว้ ...
gniourf_gniourf

หากคุณต้องการข้ามไปยังแหล่งข้อมูลโดยตรงคุณสามารถใช้(shopt -s extdebug; declare -F quote)ซึ่งจะบอกชื่อฟังก์ชั่นหมายเลขบรรทัดที่กำหนดไว้ที่และชื่อไฟล์ที่กำหนดไว้
wjandrea

3

quote เป็นฟังก์ชั่น:

quote () 
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

ฟังก์ชั่นนี้ถูกกำหนดไว้ที่ไหนสักแห่งในไฟล์เริ่มต้น bash แม่นยำยิ่งขึ้นหากคุณใช้ Ubuntu 13.04 คุณสามารถค้นหาได้/usr/share/bash-completion/bash_completionที่บรรทัด 142

ใช้คำสั่งต่อไปนี้เพื่อตรวจสอบ:

type quote

วัตถุประสงค์มีความชัดเจนอย่างชัดเจน


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