`set -e` và` grep` idiom để ngăn chặn thoát sớm khỏi tập lệnh shell khi không tìm thấy mẫu


15

Yêu cầu trợ giúp - trong ngữ cảnh shell script trên bash GNU / LINUX:

Tôi luôn luôn sử dụng set -e. Thông thường, tôi muốn grepvà không phải lúc nào cũng muốn tập lệnh chấm dứt thực thi nếu không tìm thấy greptrạng thái thoát của 1mẫu biểu thị.

Đôi khi tôi đã cố gắng giải quyết vấn đề này như sau:

(Thử I)
Nếu set +o pipefailvà gọi grep bằng một cái gì đó như thế grep 'p' | wc -lthì tôi sẽ có hành vi mong muốn cho đến khi một người bảo trì trong tương lai kích hoạt pipefail. Ngoài ra, tôi thích kích hoạt pipefailđể điều này không làm việc cho tôi.

(Thử II)
Sử dụng một sedhoặc awkvà chỉ in các dòng khớp với mẫu, sau đó wccác dòng khớp để kiểm tra mẫu phù hợp. Tôi không thích tùy chọn này vì sử dụng sedđể grepcó vẻ như một cách giải quyết cho vấn đề thật sự của tôi.

(Thử III)
Cái này là thứ tôi thích nhất - đại loại như:set +e; grep 'p'; set-e

Bất kỳ cái nhìn sâu sắc / thành ngữ sẽ được đánh giá cao nhất - cảm ơn bạn.

Câu trả lời:


19

Bạn có thể đặt grep trong một ifđiều kiện hoặc nếu bạn không quan tâm đến trạng thái thoát, hãy thêm || true.

Ví dụ: grepgiết chết vỏ

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

giải pháp 1: vứt bỏ trạng thái thoát khác không

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

Giải pháp 2: kiểm tra rõ ràng trạng thái thoát

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

Từ trang bash man thảo luận set -e:

Shell không thoát nếu lệnh bị lỗi là một phần của danh sách lệnh ngay sau một thời gian hoặc cho đến khi từ khóa, một phần của kiểm tra theo các từ dành riêng if hoặc elif , một phần của bất kỳ lệnh nào được thực thi trong danh sách && hoặc ││ ngoại trừ lệnh theo lệnh cuối cùng && hoặc ││ , bất kỳ lệnh nào trong đường ống ngoại trừ lệnh cuối cùng hoặc nếu giá trị trả về của lệnh đang được đảo ngược với ! .


Cho rằng bash trong một thời gian dài đã không thực hiện đúng - có thể là tài liệu chưa chính xác. Vì văn bản dường như giống hệt với trang man bash-3.x, xin lưu ý: tất cả các phiên bản bash trước khi bash4.0 thực hiện -e không chính xác.
schily

Cũng lưu ý rằng vì tiêu chuẩn POSIX cũng sai, chúng tôi đã thay đổi văn bản POSIX để xử lý lỗi với -e trong năm 2009
thường vào

1
@schily Vui lòng cung cấp cho con trỏ đến nơi người ta có thể tìm hiểu hành vi 'chính xác' của -e là gì, bash <4 đã làm gì khác nhau và những gì đã được thay đổi trong POSIX.
zwol

Các lỗi trong bash-3 về cơ bản làm cho nó không thể sử dụng được makevì nó không phải lúc nào cũng thoát khỏi các lỗi. Đối với các cuộc thảo luận POSIX có liên quan, bạn có thể muốn kiểm tra austingroupbugs.net
schily

@schily Bạn có thể vui lòng cụ thể hơn không?
zwol
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.