เหตุใดราคาจึงจำเป็นสำหรับอาร์กิวเมนต์ไฟล์เมื่อเรียกสคริปต์ Bash นี้


13

ฉันค่อนข้างใหม่กับการเขียนสคริปต์ Bash ฉันมี "testcript" ซึ่งฉันใช้เป็นพื้นฐานสำหรับสคริปต์ขั้นสูง / มีประโยชน์มากขึ้น:

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

เมื่อฉันเรียกสิ่งนี้โดยไม่ใส่เครื่องหมายอัญประกาศมันก็แค่หยิบไฟล์หนึ่งไฟล์ในไดเรกทอรี:

testscript *.txt

แต่เมื่อฉันเรียกมันด้วยเครื่องหมายคำพูดมันทำงานได้อย่างถูกต้องและเลือกไฟล์ข้อความทั้งหมด:

testscript '*.txt'

เกิดขึ้นที่นี่คืออะไร?


การจะมีมากมากใสวิธีที่เหมาะสมในการแก้ไขปัญหานี้คือการทำงานfor a in "$@"; do(หรือfor a; do) ในบทของคุณจึงออกจาก globbing กับเปลือกนอกไม่ได้ที่จะออกจากคำพูด
Charles Duffy


ดูดีคุ้มค่า guide.bash.academy
vascowhite

คำตอบ:


29

เมื่อคุณเรียกโปรแกรม

testscript *.txt

จากนั้นเชลล์ของคุณทำการขยายและทำงานค่าทั้งหมด ดังนั้นมันอาจจะเรียกโปรแกรมของคุณอย่างมีประสิทธิภาพ

testscript file1.txt file2.txt file3.txt file4.txt

ตอนนี้โปรแกรมของคุณดูเฉพาะและเพื่อให้ทำงานเฉพาะใน$1file1.txt

โดยการอ้างในบรรทัดคำสั่งคุณผ่านสายอักขระตัวอักษรสคริปต์และนั่นคือสิ่งที่ถูกเก็บไว้ใน*.txt วง$1ของคุณforจะขยายออก

โดยปกติแล้วคุณจะใช้"$@"และไม่ได้$1อยู่ในสคริปต์เช่นนี้

นี่คือ "gotcha" สำหรับผู้ที่มาจากการเขียนสคริปต์ CMD ที่เชลล์คำสั่งไม่ทำให้เป็นเส้นโค้ง (ตามที่ทราบ) และส่งผ่านสตริงตัวอักษรเสมอ


6
เพื่อชี้แจง (สำหรับคนอื่นที่ไม่ใช่ผู้เขียนคำตอบข้างต้น) การใช้"$@"(ตรงข้ามกับ$@หรือ$1 $2 $3) จะทำให้แต่ละชื่อไฟล์ถูกยกมา"file1.txt" "file2.txt"เป็นต้นสำหรับfile1.txtสิ่งนี้ไม่มีความหมาย แต่ถ้าคุณมีmy file.txtการอ้างถึงมีความสำคัญเพื่อป้องกันเชลล์ แยกที่จะเปิดเป็นสองชื่อไฟล์ชื่อหนึ่งและเป็นหนึ่งในชื่อmy file.txtอ้างถึงการป้อนข้อมูลของผู้ใช้และการขยาย glob เสมอว่าคุณจะไม่มีความสุขในบางวัน
Seth Robertson

2
และนี่ไม่ใช่แค่ทางทฤษฎี - Mac OS X เมื่อส่งมาพร้อมกับสคริปต์อัปเดตที่ไม่ได้อ้างถึงข้อโต้แย้งอย่างถูกต้องและจบลงด้วยการลบฮาร์ดไดรฟ์ของผู้คนในบางสถานการณ์
ปุย

2
@fluffy คุณมีลิงค์เกี่ยวกับเรื่องนี้หรือไม่?
Wildcard

@ Wildcard โชคไม่ดีที่ฉันไม่พบบทความใด ๆ เกี่ยวกับเรื่องนี้ แต่มันเป็นข่าวใหญ่ในโลกของเทคโนโลยีเมื่อมันเกิดขึ้น ฉันอยากจะบอกว่ามันเป็นในปี 2003/2004 หรือราว ๆ นั้นย้อนกลับไปเมื่อ Apple ยังคงได้รับการจำหน่ายเป็น UNIX
ปุย

1
@wildcard Ah พบแล้ว! xlr8yourmac.com/OSX/itunes2_erased_drives.html - จริงๆแล้วมันเป็นสคริปต์อัปเกรด iTunes ที่เป็นตัวการ
ปุย

7

หากไม่มีเครื่องหมายอัญประกาศเชลล์จะขยายออก*.txtก่อนที่จะเรียกใช้สคริปต์ดังนั้นจึง$1เป็นเพียงไฟล์แรกที่ได้รับการขยาย ทั้งหมดของtxtไฟล์เป็นข้อโต้แย้งสคริปต์ของคุณที่จุดที่ (สมมติว่ามีไม่มากเกินไป)

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

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