ความแตกต่างระหว่างgrep apple file
และgrep "apple" file
คืออะไร? การใส่เครื่องหมายคำพูดทำอะไร? ทั้งคู่ดูเหมือนจะทำงานและทำสิ่งเดียวกัน (แสดงบรรทัดเดียวกัน)
ความแตกต่างระหว่างgrep apple file
และgrep "apple" file
คืออะไร? การใส่เครื่องหมายคำพูดทำอะไร? ทั้งคู่ดูเหมือนจะทำงานและทำสิ่งเดียวกัน (แสดงบรรทัดเดียวกัน)
คำตอบ:
เครื่องหมายอัญประกาศมีผลต่ออักขระที่เชลล์ของคุณพิจารณาเป็นพิเศษและมีความหมายทางไวยากรณ์ ในตัวอย่างของคุณสิ่งนี้ไม่ได้สร้างความแตกต่างเพราะapple
ไม่มีอักขระดังกล่าว
แต่พิจารณาอีกตัวอย่างหนึ่ง: grep apple tree file
จะค้นหาคำapple
ในไฟล์tree
และfile
ในขณะที่grep "apple tree" file
จะค้นหาคำในไฟล์apple tree
file
เครื่องหมายคำพูดบอกว่าทุบตีว่าคำในพื้นที่"apple tree"
ไม่ได้เริ่มพารามิเตอร์ใหม่ แต่จะต้องเป็นส่วนหนึ่งของพารามิเตอร์ปัจจุบัน grep apple\ tree file
จะให้ผลลัพธ์ที่เหมือนกันเพราะ\
บอกให้ทุบตีเพื่อเพิกเฉยต่อความหมายพิเศษของตัวละครต่อไปนี้และปฏิบัติต่อมันอย่างแท้จริง
"
) และคำพูดเดียว ( '
) อัญประกาศเดี่ยวป้องกันการตีความของอักขระบางตัวเช่นใน$
ขณะที่เครื่องหมายคำพูดคู่อนุญาตการตีความ เช่นgrep '${USER}'
จะค้นหาข้อความ${USER}
ในขณะที่grep "${USER}"
จะค้นหาข้อความที่ตัวแปรUSER
มี (เช่นjohnstacen
)
อัญประกาศคู่อนุญาตให้มีการประเมินราคาอัญประกาศเดี่ยวป้องกันการประเมินผลไม่มีเครื่องหมายอัญประกาศอนุญาตให้มีการขยายสัญลักษณ์แทนเมื่อใช้บนบรรทัดคำสั่ง ในฐานะที่เป็นตัวอย่างที่วางแผนไว้:
[user@work test]$ ls .
A.txt B.txt C.txt D.cpp
# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp
[user@work test]$ echo "*"
*
[user@work test]$ echo '*'
*
# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt
[user@work test]$ echo "*.txt"
*.txt
[user@work test]$ echo '*.txt'
*.txt
[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found
[user@work test]$ myname=is\ Fred; echo $myname
is Fred
[user@work test]$ myname="is Fred"; echo $myname
is Fred
[user@work test]$ myname='is Fred'; echo $myname
is Fred
การทำความเข้าใจวิธีการทำงานของคำพูดเป็นหัวใจสำคัญในการทำความเข้าใจ Bash ตัวอย่างเช่น:
# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt
# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt
# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)
คุณสามารถใช้อัญประกาศเดี่ยวเพื่อส่งคำสั่งผ่านตัวแปร เครื่องหมายคำพูดเดี่ยวจะป้องกันการประเมินผล เครื่องหมายคำพูดคู่จะประเมิน
# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt
# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt
# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)
คุณสามารถใช้เครื่องหมายคำพูดเดี่ยวภายในเครื่องหมายคำพูดคู่และคุณสามารถใช้เครื่องหมายคำพูดคู่ภายในเครื่องหมายคำพูดคู่ แต่เครื่องหมายอัญประกาศคู่ภายในเครื่องหมายคำพูดเดี่ยวไม่ควรทำ (โดยไม่ต้องหลบหนีพวกเขา)จะไม่ถูกประเมิน ไม่ควรทำเครื่องหมายคำพูดเดี่ยวในเครื่องหมายคำพูดเดี่ยว (โดยไม่ต้องหลีกหนี)
คุณจะต้องเข้าใจราคาอย่างถี่ถ้วนเพื่อใช้ Bash อย่างมีประสิทธิภาพ สำคัญมาก!
ตามกฎทั่วไปฉันไม่ใช้เครื่องหมายอัญประกาศถ้าฉันต้องการให้ Bash ขยายบางสิ่งออกเป็นองค์ประกอบ (เช่นอาร์เรย์) ฉันใช้เครื่องหมายอัญประกาศเดี่ยวสำหรับสตริงตัวอักษรที่ไม่ได้รับการแก้ไข ที่น่าจะส่งคืนสตริงประเภทใดก็ได้ นี่คือเพื่อให้แน่ใจว่าช่องว่างและอักขระพิเศษจะถูกเก็บไว้
grep a*b equations.txt
แล้วมันจะค้นหาa*b
เว้นแต่จะมีไฟล์ในไดเรกทอรีปัจจุบันเริ่มต้นด้วย, และลงท้ายด้วย b ในกรณีนี้ (เพราะ (ba) sh จะขยายชื่อไฟล์ในบรรทัดคำสั่ง) grep จะถูกเรียกด้วย พารามิเตอร์ที่แตกต่างกันอย่างสมบูรณ์ทำให้ได้ผลลัพธ์ที่ต่างกัน นี่เป็นปัญหาที่พบได้บ่อยกว่าเนื่องจากคำสั่งเช่นfind . -name *.txt
นั้นจะส่งผลให้เกิดพฤติกรรมที่ไม่คาดคิดหากมีไฟล์ txt ในไดเรกทอรีปัจจุบัน มันจะดีกว่าที่จะใช้คำพูดในกรณีนี้