คำสั่งเพื่อแสดงข้อความที่กำหนดถ้ามีไฟล์ใดไฟล์หนึ่งอยู่


11

มีคำสั่งให้แสดงข้อความ“ ใช่” หากมีไฟล์ใดไฟล์หนึ่งอยู่หรือไม่? ไม่จำเป็นต้องให้ฟังก์ชั่นหากไฟล์ไม่มีอยู่

คำตอบ:


25

ใช้ Bash หนึ่งซับง่ายๆนี้:

if [ -e FILENAME ] ; then echo Yes ; fi

การ-eตรวจสอบจะประเมินว่าเป็นจริงหากFILENAMEมีอยู่ไม่ว่าจะเป็นอะไร (ไฟล์ไดเรกทอรีลิงก์อุปกรณ์ ... )

หากคุณต้องการตรวจสอบไฟล์ปกติให้ใช้-fแทนตามที่@Arronicalกล่าว


18
[ -e FILENAME ] && echo Yes
Zeb McCorkle

@ZebMcCorkle ถูกต้องแล้วมันก็ใช้ได้เหมือนกัน คุณอาจโพสต์นั้นเป็นคำตอบที่แยกจากกัน
ผู้บัญชาการ Byte

3
หากFILENAMEเป็นการขยายตัวตัวแปรหรือมีอักขระพิเศษใด ๆ อย่าลืมอ้างอิง เช่นในสคริปต์, [ -e "$1" ] && echo Yes.
Peter Cordes

@PeterCordes หากคุณใช้ทุบตีคุณสามารถใช้[[และ]]แทนที่จะอ้างตัวแปร
Holloway

1
@Holloway: yup แต่บางครั้งคุณต้องเขียนสคริปต์แบบพกพาที่ต้องการเพียง POSIX sh นั่นเป็นเหตุผลที่ฉันให้เวอร์ชันที่ปลอดภัยของสิ่งนี้แทนการ downvoting มันและการตอบโต้การตอบกลับอย่างรวดเร็ว โปรดทราบว่ามันไม่ใช่ปัญหาที่จะอ้างถึงการขยายตัวภายในการ[[ ]]อ้างอิงเป็นนิสัยที่ดีสำหรับผู้เริ่มต้นที่ไม่จำกฎพิเศษสำหรับ[[ ]]ผู้ปฏิบัติงานหรือสำหรับบริบททางคณิตศาสตร์
Peter Cordes

10

คุณสามารถใช้สคริปต์ง่ายๆนี้:

#!/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

2
ดี "$1"แต่เจ้าจงพูดอ้างอิงตัวแปรเช่น ถ้ามันมีพื้นที่สีขาวอยู่ภายในมันจะพังโดยไม่มีคำพูดและสิ่งเลวร้ายอื่น ๆ สามารถเกิดขึ้นได้
Joe

9

ในเปลือก bash บนบรรทัดคำสั่ง

if [[ -f /path/to/file ]]; then echo "Yes"; fi

ใช้ตัวดำเนินการตามเงื่อนไขของ bash -fและกำลังตรวจสอบว่ามีไฟล์อยู่หรือไม่และเป็นไฟล์ปกติ หากคุณต้องการที่จะทดสอบสำหรับไฟล์ใด ๆ -eรวมทั้งไดเรกทอรีและการเชื่อมโยงการใช้งานแล้ว

นี่เป็นแหล่งข้อมูลที่ดีสำหรับการทุบตีเงื่อนไข


1
ทำไมต้องจัดฟันแบบคู่
ผู้บัญชาการ Byte

1
ฉันไม่ใช่แฟนของtestมันในรูปแบบดั้งเดิมฉันรู้ว่ามันเกินความจริง แต่เป็นนิสัยของฉัน
59

7
@ ByteCommander: การจัดฟันสองครั้งโดยทั่วไปจะดีกว่าการจัดฟันแบบเดี่ยว พวกมันเป็นส่วนหนึ่งของไวยากรณ์เชลล์ (แทนที่จะเรียกใช้[คำสั่งซึ่งมักเรียกว่า builtin) พวกมันแก้ไขความไม่สอดคล้องและพฤติกรรมโง่ของเวอร์ชันรั้งเดี่ยว [builtin ยังคงใช้งานได้ แต่ฉันไม่เห็นเหตุผลที่ดีที่จะใช้มันในรหัสทุบตีใหม่ (หากคุณจำเป็นต้องเขียนสคริปต์ที่สอดคล้องกับ POSIX ที่สามารถทำงานบนเชลล์โบราณหรืออะไรบางอย่างมันก็แตกต่างกัน)
Nick Matteo

@ kundor: ตกลงกันเป็นส่วนใหญ่ถึงจะยุติธรรม " [มักจะเรียกว่า builtin" เป็นที่น่าสงสัย type -a [สำหรับฉันแสดง "shell builtin" จากนั้น " /usr/bin/[."
wchargin

1
@wchargin: ฉันกลัวว่าฉันไม่เข้าใจว่าคุณกำลังทำอะไรอยู่ typeดูเหมือนว่าผลลัพธ์ของคุณจะยืนยันสิ่งที่ฉันพูดไม่ได้?
Nick Matteo

5

คำสั่งสั้นที่สุดสำหรับการทำสิ่งที่คุณต้องการคือ:

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จะเทียบเท่ายกเว้นว่าเรียกร้องให้ยุติ[]


4

หากต้องการสกินคำถามประเภทนี้มีหลายวิธีและนี่เป็นอีกคำถามหนึ่ง: ใช้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 '' "
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.