มีคำสั่งให้แสดงข้อความ“ ใช่” หากมีไฟล์ใดไฟล์หนึ่งอยู่หรือไม่? ไม่จำเป็นต้องให้ฟังก์ชั่นหากไฟล์ไม่มีอยู่
มีคำสั่งให้แสดงข้อความ“ ใช่” หากมีไฟล์ใดไฟล์หนึ่งอยู่หรือไม่? ไม่จำเป็นต้องให้ฟังก์ชั่นหากไฟล์ไม่มีอยู่
คำตอบ:
ใช้ Bash หนึ่งซับง่ายๆนี้:
if [ -e FILENAME ] ; then echo Yes ; fi
การ-eตรวจสอบจะประเมินว่าเป็นจริงหากFILENAMEมีอยู่ไม่ว่าจะเป็นอะไร (ไฟล์ไดเรกทอรีลิงก์อุปกรณ์ ... )
หากคุณต้องการตรวจสอบไฟล์ปกติให้ใช้-fแทนตามที่@Arronicalกล่าว
FILENAMEเป็นการขยายตัวตัวแปรหรือมีอักขระพิเศษใด ๆ อย่าลืมอ้างอิง เช่นในสคริปต์, [ -e "$1" ] && echo Yes.
[[และ]]แทนที่จะอ้างตัวแปร
[[ ]]อ้างอิงเป็นนิสัยที่ดีสำหรับผู้เริ่มต้นที่ไม่จำกฎพิเศษสำหรับ[[ ]]ผู้ปฏิบัติงานหรือสำหรับบริบททางคณิตศาสตร์
คุณสามารถใช้สคริปต์ง่ายๆนี้:
#!/bin/bash
if [[ -f $1 ]]; then
echo "Yes"
exit 0
else
exit 1
fi
file-exists.shบันทึกเป็น chmod +x file-exists.shจากนั้นในเทอร์มิพิมพ์
ใช้เช่น: ./file-exists.sh FILEที่คุณแทนที่FILEด้วยไฟล์ที่คุณต้องการตรวจสอบตัวอย่างเช่น:
./file-exists.sh file.txt
หากfile.txtมีอยู่Yesจะถูกพิมพ์ไปยังเทอร์มินัลและโปรแกรมจะออกจากสถานะ 0 (สำเร็จ) หากไม่มีไฟล์อยู่จะไม่มีสิ่งใดพิมพ์ออกมาและโปรแกรมจะออกจากสถานะ 1 (ความล้มเหลว)
หากคุณสงสัยว่าทำไมฉันจึงรวมexitคำสั่งอ่านต่อ ...
exitคำสั่ง?exitทำให้เกิดการยกเลิกกระบวนการปกติ สิ่งนี้หมายความว่าอะไรโดยพื้นฐาน: มันหยุดสคริปต์ ยอมรับพารามิเตอร์ทางเลือก (ตัวเลข) ที่จะเป็นสถานะออกของสคริปต์ที่เรียกว่า
สถานะการออกนี้ช่วยให้สคริปต์อื่น ๆ ของคุณสามารถใช้file-existsสคริปต์ของคุณและเป็นวิธีที่พวกเขารู้ว่าไฟล์นั้นมีอยู่หรือไม่
ตัวอย่างง่ายๆที่ทำให้สิ่งนี้ใช้คือสคริปต์นี้ (บันทึกเป็นfile-exists-cli.sh):
#!/bin/bash
echo "Enter a filename and I will tell you if it exists or not: "
read FILE
# Run `file-exists.sh` but discard any output because we don't need it in this example
./file-exists.sh $FILE &>> /dev/null
# #? is a special variable that holds the exit status of the previous command
if [[ $? == 0 ]]; then
echo "$FILE exists"
else
echo "$FILE does not exist"
fi
ทำตามปกติแล้วเรียกใช้:chmod +x file-exists-cli.sh ./file-exists-cli.shคุณจะเห็นสิ่งนี้:
มีไฟล์ ( exit 0):
➜ ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not:
booleans.py
booleans.py exists
ไม่มีไฟล์ ( exit 1):
➜ ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not:
asdf
asdf does not exist
"$1"แต่เจ้าจงพูดอ้างอิงตัวแปรเช่น ถ้ามันมีพื้นที่สีขาวอยู่ภายในมันจะพังโดยไม่มีคำพูดและสิ่งเลวร้ายอื่น ๆ สามารถเกิดขึ้นได้
ในเปลือก bash บนบรรทัดคำสั่ง
if [[ -f /path/to/file ]]; then echo "Yes"; fi
ใช้ตัวดำเนินการตามเงื่อนไขของ bash -fและกำลังตรวจสอบว่ามีไฟล์อยู่หรือไม่และเป็นไฟล์ปกติ หากคุณต้องการที่จะทดสอบสำหรับไฟล์ใด ๆ -eรวมทั้งไดเรกทอรีและการเชื่อมโยงการใช้งานแล้ว
testมันในรูปแบบดั้งเดิมฉันรู้ว่ามันเกินความจริง แต่เป็นนิสัยของฉัน
[คำสั่งซึ่งมักเรียกว่า builtin) พวกมันแก้ไขความไม่สอดคล้องและพฤติกรรมโง่ของเวอร์ชันรั้งเดี่ยว [builtin ยังคงใช้งานได้ แต่ฉันไม่เห็นเหตุผลที่ดีที่จะใช้มันในรหัสทุบตีใหม่ (หากคุณจำเป็นต้องเขียนสคริปต์ที่สอดคล้องกับ POSIX ที่สามารถทำงานบนเชลล์โบราณหรืออะไรบางอย่างมันก็แตกต่างกัน)
[มักจะเรียกว่า builtin" เป็นที่น่าสงสัย type -a [สำหรับฉันแสดง "shell builtin" จากนั้น " /usr/bin/[."
typeดูเหมือนว่าผลลัพธ์ของคุณจะยืนยันสิ่งที่ฉันพูดไม่ได้?
คำสั่งสั้นที่สุดสำหรับการทำสิ่งที่คุณต้องการคือ:
test -e FILENAME && echo Yes
test -eจะทดสอบว่ามีชื่ออยู่ในระบบไฟล์หรือไม่ (คุณสามารถใช้test -fเพื่อ จำกัด ไฟล์ปกติเท่านั้นดูman testเพิ่มเติม)
หากเงื่อนไขที่กำหนดประเมินเป็นจริงแล้วtestส่งคืนสถานะการออกที่สำเร็จ (มิฉะนั้นจะส่งคืนสถานะความล้มเหลว) เรารวมคำสั่งสองคำสั่งเข้าด้วย&&กันซึ่งหมายถึง "ดำเนินการคำสั่งถัดไปหากคำสั่งก่อนหน้าออกจากสถานะสำเร็จ" คำสั่งถัดไปพิมพ์Yesบนเอาต์พุตมาตรฐาน ในกรณีของเชลล์แบบโต้ตอบบนเทอร์มินัล
สิ่งนี้หลีกเลี่ยงเนื้อหาที่เป็นข้อความเพิ่มเติมของifข้อความสั่ง แต่ให้ผลลัพธ์เหมือนกัน การใช้&&(หรือตรงกันข้าม||) เพื่อผูกคำสั่งเข้าด้วยกันทำงานได้ดีเมื่อมีคำสั่งเดียวเกี่ยวข้อง หากคุณต้องการทำมากกว่ารันคำสั่งเดียวเพื่อตอบสนองสถานะการออกของคำสั่งเดียวจากนั้นการใช้ifไวยากรณ์จะอ่านได้เร็วขึ้น
ดังที่ได้กล่าวแล้วในคำตอบอื่น ๆ การifสร้างรูปแบบที่เทียบเท่าจะเป็น:
if test -e FILENAME; then echo Yes; fi
หรืออีกทางหนึ่ง:
if test -e FILENAME
then
echo Yes
fi
เพื่อวัตถุประสงค์เหล่านี้[และtestจะเทียบเท่ายกเว้นว่าเรียกร้องให้ยุติ[]
หากต้องการสกินคำถามประเภทนี้มีหลายวิธีและนี่เป็นอีกคำถามหนึ่ง: ใช้findคำสั่งด้วยการ-execตั้งค่าสถานะ เส้นทางไปยังไฟล์สามารถแบ่งออกเป็นสองส่วนfind /etcซึ่งกำหนดไดเรกทอรีและ-name FILENAMEที่ระบุชื่อไฟล์ (duh!) -maxdepthจะfindทำงานกับ/etcไดเรกทอรีเท่านั้นและจะไม่ลงไปในไดเรกทอรีย่อย
adminx@L455D:~$ find /etc -maxdepth 1 -name passwd -exec printf "YES\n" \;
YES
adminx@L455D:~$ find /etc -maxdepth 1 -name passwd1 -exec printf "YES\n" \;
adminx@L455D:~$
อีกวิธีหนึ่งผ่านstat:
adminx@L455D:~$ stat /etc/passwd1 &>/dev/null && echo YES
adminx@L455D:~$ stat /etc/passwd &>/dev/null && echo YES
YES
และอีกทางผ่านหลาม:
>>> import os
>>> if os.stat('/etc/passwd'):
... print 'YES'
...
YES
>>> if os.stat('/etc/passwd1'):
... print 'YES'
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/etc/passwd1'
หรือทางเลือกบรรทัดคำสั่งสั้น ๆ :
python -c "from os.path import exists; print 'Yes' if exists('/etc/fstab') else '' "
[ -e FILENAME ] && echo Yes