Sử dụng grep với đường ống và dấu và để lọc lỗi từ find


22

Tôi đang sử dụng cygwin để tìm một tập tin trên cygdrive.

Tuy nhiên, tôi cần phải loại bỏ các thông báo từ chối cấp phép (nếu không, kết quả sẽ bị ẩn trong các thông báo lỗi). Lệnh sau hoạt động:

find -name 'myfile.*' |& grep -v "Permission denied"

Tôi không hiểu tại sao ampersand cần được đưa vào lệnh này, sẽ mong nó hoạt động nhưng nó không hoạt động.

find -name 'myfile.*' | grep -v "Permission denied"

Hãy giải thích ý nghĩa của ký hiệu.

Câu trả lời:


24

Trong các hệ thống giống như Unix, có hai đường dẫn đầu ra mà nếu không được sửa đổi sẽ gửi đầu ra đến màn hình của bạn. Lỗi tiêu chuẩn (hoặc stderr) là lỗi gây ra hầu hết các lỗi và điều kiện lỗi.

Để chuyển thông báo bị từ chối cấp phép trong thiết bị lỗi chuẩn cho cùng một luồng đầu ra là "đầu ra thông thường", bạn phải kết hợp cả hai. Trong ví dụ của bạn, để bạn grep -vvận hành đúng cách trên nó, bạn kết hợp thiết bị xuất chuẩn (đầu ra tiêu chuẩn) và thiết bị xuất chuẩn với cú pháp phức tạp mà bạn thấy.

Từ GNU Bash thủ công phần 3.2.2 Đường ống :

Nếu ' |&' được sử dụng, lỗi tiêu chuẩn của Command1 , ngoài đầu ra tiêu chuẩn của nó, được kết nối với đầu vào tiêu chuẩn của Command2 qua ống; nó là tốc ký cho 2>&1 |. Chuyển hướng ngầm định này của lỗi tiêu chuẩn đến đầu ra tiêu chuẩn được thực hiện sau khi bất kỳ chuyển hướng nào được chỉ định bởi lệnh.

Ngoài ra, như geirha chỉ ra, nếu bạn muốn loại bỏ đầu ra stderr, bạn sẽ muốn làm một cái gì đó như

find -name 'myfile.*' 2> /dev/null

hoặc có lẽ

find -name 'myfile.*' 2> /tmp/errorlog

Và lưu ý rằng nếu bạn có các chuỗi lệnh, chẳng hạn như findchuyển đầu ra của nó cho xargsbạn, bạn sẽ cần đặt toàn bộ đường dẫn của lệnh trong ngoặc đơn để nắm bắt đầu ra từ tất cả các thành phần của lệnh. Ví dụ,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

Nếu bạn bỏ dấu ngoặc đơn và thay vào đó, hãy thực hiện -

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

bạn vẫn sẽ thấy các quyền bị từ chối lỗi từ find hoặc egrep, nhưng stderr sẽ được chuyển hướng cho xargs.

Như bạn đã thấy, bạn chỉ có thể vứt bỏ thiết bị lỗi chuẩn sau khi xem nội dung của nó trong quá trình chạy thử.

Lưu ý rằng với GNU findvà theo như tôi có thể nói, bất kỳ tuân thủ POSIX nào find, -printtùy chọn này đều ẩn. Bạn vẫn có thể cung cấp nó một cách rõ ràng nếu bạn muốn.



1
@LukeExton Có. Trong các shell khác, 2>&1 |có thể được sử dụng thay cho |&(nghĩa là, người ta có thể chuyển hướng rõ ràng stderr sang stdout và sau đó chuyển nó sang lệnh tiếp theo trong đường ống).
Eliah Kagan

2> >( grep filter )cũng tiện dụng
user1133275


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.