มีคำสั่งให้แสดงข้อความ“ ใช่” หากมีไฟล์ใดไฟล์หนึ่งอยู่หรือไม่? ไม่จำเป็นต้องให้ฟังก์ชั่นหากไฟล์ไม่มีอยู่
มีคำสั่งให้แสดงข้อความ“ ใช่” หากมีไฟล์ใดไฟล์หนึ่งอยู่หรือไม่? ไม่จำเป็นต้องให้ฟังก์ชั่นหากไฟล์ไม่มีอยู่
คำตอบ:
ใช้ 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