Kiểm tra xem đầu ra của một lệnh có chứa một chuỗi nhất định trong tập lệnh shell hay không


116

Tôi đang viết một tập lệnh shell và tôi đang cố gắng kiểm tra xem đầu ra của một lệnh có chứa một chuỗi nhất định hay không. Tôi đang nghĩ mình có thể phải sử dụng grep, nhưng tôi không chắc làm thế nào. Có ai biết không?


Lệnh có cần tiếp tục chạy sau khi tạo chuỗi đầu ra mà bạn đang tìm kiếm không hay nó có thể được đóng ngay tại thời điểm đó? (Hai câu trả lời của bạn khác nhau về ngữ nghĩa của chúng về mặt này).
Charles Duffy

Câu trả lời:


97

Kiểm tra giá trị trả về của grep:

./somecommand | grep 'string' &> /dev/null
if [ $? == 0 ]; then
   echo "matched"
fi

được thực hiện một cách thành ngữ như vậy:

if ./somecommand | grep -q 'string'; then
   echo "matched"
fi

và cả:

./somecommand | grep -q 'string' && echo 'matched'

2
Mã này không hoạt động với tất cả các shell POSIX: Tiêu chuẩn POSIX chỉ yêu cầu =là một toán tử so sánh, không phải ==; xem pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
Charles Duffy

4
Ngoài ra, grep 'string' &>/dev/nullcả hai đều không tuân thủ POSIX và thực thi chậm hơn nhiều (nếu stringxuất hiện sớm trong một luồng đầu ra dài) hơn grep -q string. [Cảnh báo ở đó là nếu bạn muốn đảm bảo somecommandtiếp tục chạy ngay cả sau khi phát ra string, trong trường hợp đó việc sử dụng grep -q- bằng cách đóng stdin của nó và thoát ra sau khi phiên bản đầu tiên stringđược nhìn thấy - có thể phản tác dụng]. (Re: "không tuân thủ POSIX", &>là một tiện ích mở rộng - xem pubs.opengroup.org/onlinepubs/009695399/utilities/… mô tả hỗ trợ chuyển hướng bắt buộc POSIX).
Charles Duffy,

Sẽ giúp đỡ nếu nó được giải thích lý do tại sao tác phẩm / những gì mỗi tham số không, để khuyến khích sự hiểu biết đầy đủ về cú pháp
redfox05

157

Thử nghiệm $?là một mô hình chống

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi

Nếu có cơ hội nào bạn chỉ muốn thử nghiệm một chuỗi cố định, thêm Fx lựa chọn: grep -Fxq F là viết tắt của cố định (không giải thích) và x cho toàn bộ tuyến
Erdal G.

4
Tại sao thử nghiệm $?là chống mẫu?
Vitaly Zdanevich

1
@VitalyZdanevich Tôi giả sử như vậy vì nó không mạnh so với đồng thời.
Konrad Reiche

@VitalyZdanevich, đối với một thử nghiệm $?không đặt các lệnh trước đó là "đã kiểm tra" cho các mục đích set -ehoặc ERRbẫy, vì vậy chương trình của bạn có thể thoát trong các trường hợp bạn muốn nó chỉ đơn giản là quay lại đường dẫn cố ý-sai sau đó. Đối với một $?trạng thái toàn cầu khác, là trạng thái toàn cầu dễ bay hơi - thật dễ dàng để vô tình vứt bỏ giá trị của nó. Ví dụ: nếu bạn thêm một dòng ghi nhật ký như echo "Exit status is $?", giá trị mới trong $?sẽ trở thành trạng thái thoát của echo.
Charles Duffy

6

Một tùy chọn khác là kiểm tra kết quả khớp biểu thức chính quy trên đầu ra lệnh.

Ví dụ:

[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"

1

Tập lệnh shell có điều kiện if / else sạch:

if ./somecommand | grep -q 'some_string'; then
  echo "exists"
else
  echo "doesn't exist"
fi
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.