Tôi có thể thực hiện `find` trả về 0 không khi không tìm thấy tệp phù hợp?


46

Ngay cả khi /tmpkhông có tệp nào được gọi something, tìm kiếm với nó findsẽ trả về 0:

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

Làm thế nào tôi có thể có được trạng thái thoát không bằng 0 khi findkhông tìm thấy gì?

Câu trả lời:


44

Đây là một lớp lót mà tôi tin là làm những gì bạn muốn:

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

Trạng thái trả về sẽ là 0khi một cái gì đó được tìm thấy, và khác không.

Nếu bạn cũng cần nắm bắt đầu ra findđể xử lý thêm, thì câu trả lời của Sven đã đề cập đến điều đó.


14
Các dấu vết *trên egrepregex là hoàn toàn dư thừa. Vì bạn không sử dụng egrepcú pháp biểu thức chính quy, đơn giản cũ grepcó thể nhanh hơn vài micrô giây.
tripleee

tôi đã học cách sử dụngfind ... | read
Sam

14

Giải pháp đơn giản nhất không in, nhưng thoát 0 khi tìm thấy kết quả

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

2
Báo giá kép không phục vụ mục đích ở đây.
haridsv

Mặc dù dấu ngoặc kép không có chức năng mã, nhưng chúng làm cho người đọc thấy rõ hơn rằng ký tự dấu chấm là biểu thức chính quy chứ không phải thư mục.
Dharma Bellamkonda

13

Thoát 0 dễ dàng với tìm kiếm, thoát> 0 khó hơn vì điều đó thường chỉ xảy ra với một lỗi. Tuy nhiên chúng ta có thể làm cho nó xảy ra:

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

2
Theo như tôi có thể nói, điều này không hoạt động. Mã thoát của finddường như không phụ thuộc vào mã thoát của bất kỳ -execs nào nó chạy.
Chris

@Chris làm việc cho tôi và 4 người đã ủng hộ
Steven Penny

ví dụ cho kết quả sai của giải pháp này: find / current-start-point / non-current-start-point -name file-in-current-start-point -exec false {} +
Gerald Schade

2
Điều này không hoạt động chính xác, và được ghi lại (mặc dù ẩn trong execphần, không dưới giá trị trả về). Nó không thể phân biệt giữa không tìm thấy gì và tự tìm ra lỗi (ví dụ: khi nó được gọi trên điểm bắt đầu không tồn tại).
Tgr

Nếu bạn cần chức năng này - có
Gerald Schade

7

Vừa tìm thấy câu hỏi này trong khi cố gắng tìm cách giải quyết vấn đề với Puppet (thay đổi quyền trên các thư mục trong một thư mục nhưng không phải trên chính thư mục đó), điều này có vẻ hoạt động:

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

Trường hợp sử dụng cụ thể của tôi là thế này:

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

Sẽ thoát mã 1 nếu lệnh find không tìm thấy tệp nào có quyền yêu cầu.


Một vài giải pháp (không thử tất cả) ở đây không hoạt động trên máy Mac; điều này đã làm
Hội trường Alex

5

Điều đó là không thể. Tìm trả về 0 nếu nó thoát thành công, ngay cả khi nó không tìm thấy tệp (đó là kết quả chính xác không chỉ ra lỗi khi tệp thực sự không tồn tại).

Để báo giá tìm trang

TÌNH TRẠNG EXIT

tìm lối thoát với trạng thái 0 nếu tất cả các tệp được xử lý thành công, lớn hơn 0 nếu xảy ra lỗi. Đây cố tình là một mô tả rất rộng, nhưng nếu giá trị trả về là khác không, bạn không nên dựa vào tính chính xác của kết quả tìm kiếm.

Tùy thuộc vào những gì bạn muốn đạt được, bạn có thể thử tìm -printtên tệp và kiểm tra đầu ra của nó:

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

Điều đó chắc chắn là có thể , mặc dù không mạnh mẽ như người ta có thể muốn.
Ruslan

Trang hướng dẫn được tổ chức kém; những gì Ruslan nói được ghi lại trong exec/ execdirtùy chọn (được sử dụng với +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

Tôi cảm thấy rằng đây là phương pháp ngắn gọn và trực tiếp nhất:

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

2
Trong trường hợp này, nếu find có lỗi, nó sẽ in kết quả thành / dev / null, trả về một lối thoát khác không, và sau đó sửa nó thành 0 bằng lệnh kiểm tra.
Jeff Ferland

Tôi không tin đó là sự thật. Hãy mô tả ví dụ của bạn. Nếu có lỗi và tìm lối thoát, thì chuỗi sẽ trống và kiểm tra sẽ trả về khác không.
danorton

Tôi không chắc ví dụ của bạn có thể là gì, nhưng tôi đã vô tình bỏ qua -print -quit, điều này có thể giải quyết mối quan tâm của bạn.
danorton

Có lẽ người khác đã hạ cấp (có lẽ vì lý do tương tự) có thể cung cấp một ví dụ trái ngược?
danorton

1
Được rồi, bạn không thích phong cách của tôi. Đối với các trường hợp sử dụng của tôi, bất kỳ lỗi nào có thể báo cáo là tiếng ồn hoặc nghiêm trọng đến mức chúng sẽ xuất hiện ở nơi khác. Trong mọi trường hợp, phương pháp này trả lời đúng câu hỏi cuối cùng: "Có tệp có thể truy cập trong đường dẫn theo tên đã cho không." Một lỗi sẽ trả về một câu trả lời đúng là "Không". Nếu tôi muốn tìm hiểu tại sao không, tôi có thể thêm mã phức tạp hơn để trả lời các câu hỏi không được đặt ra ở đây.
danorton

0

Đây là một kịch bản nhỏ mà tôi đã gọi test.py. Nó cải thiện các phương thức khác được đăng ở chỗ nó sẽ trả về mã lỗi nếu một phương thức được đặt và nó cũng đặt một phương thức nếu tìm thấy không liệt kê bất kỳ tệp nào:

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)

Đây là đầu ra dòng lệnh:

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

Sau đó, đối với kết quả tìm thấy có lỗi nhưng tìm thấy tệp:

$ 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

Sau đó, nếu bạn muốn danh sách các tệp bạn có thể sử dụng -print 0được chuyển đến findvà phân tách biến ra thành null hoặc bạn chỉ có thể thêm một câu lệnh in cho nó.


-1

Nó không chỉ findtrả về mã trạng thái thoát là 0 khi thành công. Trong unix những gì bạn thực hiện lệnh, nếu nó thành công thì nó sẽ trả về trạng thái thoát là 0.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.