ฉันสามารถสร้าง `find` return non-0 เมื่อไม่พบไฟล์ที่ตรงกันได้หรือไม่?


46

แม้ในขณะที่/tmpไม่มีไฟล์ที่เรียกsomethingค้นหาด้วยfindจะกลับ 0:

  $ find /tmp -name something 
  $ echo $?
  0

ฉันจะได้รับสถานะการออกที่ไม่ใช่ศูนย์findได้อย่างไรเมื่อไม่พบสิ่งใด

คำตอบ:


44

นี่คือหนึ่งในสายการบินที่ฉันเชื่อว่าทำในสิ่งที่คุณต้องการ:

find /tmp -name something | egrep '.*'

สถานะการส่งคืนจะเป็น0เมื่อพบบางสิ่งและไม่เป็นศูนย์

หากคุณต้องการบันทึกผลลัพธ์findสำหรับการประมวลผลเพิ่มเติมคำตอบของ Sven ก็ครอบคลุมไปด้วย


14
การสืบค้นกลับ*บนegrepregex ซ้ำซ้อนอย่างสมบูรณ์ เนื่องจากคุณไม่ได้ใช้egrepไวยากรณ์นิพจน์ปกติผู้สูงอายุgrepอาจจะเร็วกว่าสองสามไมโครวินาที
tripleee

ฉันเรียนรู้ที่จะใช้find ... | read
Sam

14

ทางออกที่ง่ายที่สุดที่ไม่ได้พิมพ์ แต่ออกจาก 0 เมื่อพบผลลัพธ์

find /tmp -name something | grep -q "."

2
การเสนอราคาสองครั้งไม่มีวัตถุประสงค์ที่นี่
haridsv

ในขณะที่เครื่องหมายคำพูดคู่ไม่มีการใช้งานฟังก์ชั่นโค้ด แต่จะทำให้ชัดเจนยิ่งขึ้นต่อผู้อ่านว่าอักขระจุดเป็น regex และไม่ใช่ไดเรกทอรี
Dharma Bellamkonda

13

Exit 0 นั้นง่ายต่อการค้นหา exit> 0 นั้นยากกว่าเพราะโดยปกติแล้วจะเกิดข้อผิดพลาดเท่านั้น อย่างไรก็ตามเราสามารถทำให้มันเกิดขึ้น:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

2
เท่าที่ฉันสามารถบอกได้ว่านี่ไม่ได้ผล findดูเหมือนว่ารหัสทางออกของจะไม่ขึ้นอยู่กับรหัสทางออกของสิ่งใดก็ตาม-execที่ทำงานอยู่
Chris

@Chris ใช้งานได้สำหรับฉันและ 4 คนที่โหวตขึ้น
Steven Penny

ตัวอย่างสำหรับผลลัพธ์ที่ผิดพลาดอย่างผิดพลาดของการแก้ปัญหานี้: ค้นหา / จุดเริ่มต้นที่มีอยู่ / ไม่มีจุดเริ่มต้นที่มีอยู่ - ชื่อไฟล์ - ในที่มีอยู่ - จุดเริ่มต้น --exec เท็จ {} +
Gerald Schade

2
สิ่งนี้ทำงานได้อย่างถูกต้องและมีการบันทึกไว้ (แม้ว่าจะซ่อนอยู่ในexecส่วนไม่ใช่ภายใต้ค่าส่งคืน) ไม่สามารถแยกความแตกต่างระหว่างสิ่งที่พบและพบว่าตัวเองมีข้อผิดพลาด (เช่นเมื่อถูกเรียกใช้บนจุดเริ่มต้นที่ไม่มีอยู่จริง)
Tgr

ถ้าคุณต้องการฟังก์ชั่นนี้ - ใช่
Gerald Schade

7

เมื่อพบคำถามนี้ในขณะที่พยายามหาวิธีแก้ไขปัญหา Puppet (เปลี่ยนการอนุญาตในโฟลเดอร์ภายใต้ไดเรกทอรี แต่ไม่ใช่ในไดเรกทอรี) ดูเหมือนว่าจะทำงานได้:

! test -z $(find /tmp -name something)

กรณีใช้งานเฉพาะของฉันคือ:

! test -z $(find /home -mindepth 1 -maxdepth 1 -perm -711)

ซึ่งจะออกจากรหัส 1 หากคำสั่ง find ไม่พบไฟล์ที่มีสิทธิ์ที่จำเป็น


วิธีแก้ปัญหาบางอย่าง (ไม่ลองทั้งหมด) ที่นี่ใช้ไม่ได้กับ Mac สิ่งนี้ทำ
Alex Hall

5

มันเป็นไปไม่ได้. Find ส่งคืนค่า 0 หากออกจากระบบสำเร็จแม้ว่าจะไม่พบไฟล์ (ซึ่งเป็นผลลัพธ์ที่ถูกต้องไม่ได้ระบุข้อผิดพลาดเมื่อไม่มีไฟล์จริง ๆ )

เพื่ออ้างถึงค้นหา manpage

ออกจากสถานะ

ค้นหาทางออกด้วยสถานะ 0 หากไฟล์ทั้งหมดได้รับการประมวลผลสำเร็จมากกว่า 0 ถ้าเกิดข้อผิดพลาด นี่เป็นคำอธิบายที่กว้างมากโดยเจตนา แต่ถ้าค่าส่งคืนไม่ใช่ศูนย์คุณไม่ควรพึ่งพาความถูกต้องของผลลัพธ์การค้นหา

ขึ้นอยู่กับสิ่งที่คุณต้องการบรรลุคุณสามารถลองค้นหา-printชื่อไฟล์และทดสอบกับผลลัพธ์ของมัน:

#!/bin/bash
MYVAR=`find . -name "something" -print`
if [ -z "$MYVAR" ]; then
    echo "Notfound"
else
   echo $MYVAR
fi

เป็นไปได้อย่างแน่นอนแม้ว่าจะไม่แข็งแกร่งเท่าที่ต้องการ
Ruslan

หน้าคู่มือมีการจัดระเบียบไม่ดี สิ่งที่ Ruslan กล่าวนั้นได้รับการบันทึกไว้ภายใต้ตัวเลือกexec/ execdir(ใช้กับ+):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

ฉันรู้สึกว่านี่เป็นวิธีที่กระชับและตรงที่สุด:

test `find /tmp/ -name something -print -quit 2>/dev/null`

2
ในกรณีนี้หากพบว่ามีข้อผิดพลาดมันจะพิมพ์ผลลัพธ์เป็น / dev / null ส่งคืนทางออกที่ไม่เป็นศูนย์และจากนั้นให้แก้ไขเป็น 0 โดยคำสั่งทดสอบ
Jeff Ferland

ฉันไม่เชื่อว่าเป็นเรื่องจริง โปรดอธิบายตัวอย่างของคุณ หากมีข้อผิดพลาดและค้นหาทางออกสตริงจะว่างเปล่าและการทดสอบจะส่งกลับไม่ใช่ศูนย์
danorton

ฉันไม่แน่ใจว่าสิ่งที่ตัวอย่างของคุณอาจเป็น แต่ฉันไม่ได้ตั้งใจ-print -quitซึ่งอาจแก้ไขข้อกังวลของคุณ
danorton

บางทีคนอื่น ๆ ที่ถูกลดทอนลง (น่าจะด้วยเหตุผลเดียวกัน) อาจเป็นตัวอย่างที่ตรงกันข้าม?
danorton

1
โอเคคุณไม่ชอบสไตล์ของฉัน สำหรับกรณีการใช้งานของฉันข้อผิดพลาดที่พบอาจรายงานว่าเป็นเสียงรบกวนหรือร้ายแรงมากซึ่งจะปรากฏขึ้นที่อื่น ไม่ว่าในกรณีใดวิธีนี้จะตอบคำถามสุดท้ายอย่างถูกต้อง: "มีไฟล์ที่สามารถเข้าถึงได้ในพา ธ ด้วยชื่อที่ให้" ข้อผิดพลาดจะส่งคืนคำตอบที่ถูกต้องของ "ไม่" หากฉันต้องการทราบสาเหตุที่ไม่ฉันสามารถเพิ่มรหัสที่ซับซ้อนมากขึ้นที่ตอบคำถามที่ไม่ได้โพสต์ไว้ที่นี่
danorton

0

นี่คือฉันสคริปต์เล็ก ๆ น้อย ๆ test.pyที่เรียกว่า จะปรับปรุงตามวิธีการอื่น ๆ ที่โพสต์ซึ่งจะส่งคืนรหัสข้อผิดพลาดหากมีการตั้งค่าไว้และจะเพิ่มหนึ่งหากพบไม่ได้แสดงรายการไฟล์ใด ๆ :

from subprocess import Popen
import sys

p = Popen(['find'] + sys.argv)
out, err = p.communicate()
if p.returncode:
    sys.exit(p.returncode)
if not out:
    sys.exit(1)

นี่คือเอาต์พุตบรรทัดคำสั่ง:

$ python test.py . -maxdepth 1 -name notthere
$ echo $?
1
$ find . -maxdepth 1 -name notthere
$ echo $?
0
$ find . -failedarg
find: unknown predicate `-failedarg'
$ echo $?
1

จากนั้นสำหรับผลลัพธ์ที่พบว่ามีข้อผิดพลาด แต่พบไฟล์:

$ ls -lh
$ d---------  2 jeff users   6 Feb  6 11:49 noentry
$ find .
.
./noentry
find: `./noentry': Permission denied
$ echo $?
1
$ find . | egrep '.*'
.
./noentry
find: `./noentry': Permission denied
$ echo $?
0
python ../test.py 
../test.py
$ echo $?
1

จากนั้นหากคุณต้องการรายชื่อไฟล์คุณสามารถใช้-print 0ผ่านfindและแยกตัวแปรออกเป็นโมฆะหรือคุณเพียงแค่เพิ่มคำสั่งพิมพ์


-1

ไม่เพียงfindส่งคืนรหัสสถานะการออกเป็นศูนย์เมื่อสำเร็จ ในยูนิกซ์สิ่งที่คำสั่งที่คุณดำเนินการถ้ามันประสบความสำเร็จก็จะส่งกลับสถานะออกเป็นศูนย์

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