ngăn xargs thoát khỏi lỗi


27

Theo trang man, xargs sẽ thoát nếu một trong các dòng thực thi thoát với lỗi 255:

Nếu bất kỳ lệnh gọi nào thoát ra với trạng thái 255, xargs sẽ dừng ngay lập tức mà không cần đọc thêm bất kỳ đầu vào nào. Một thông báo lỗi được đưa ra trên thiết bị lỗi chuẩn khi điều này xảy ra.

Làm thế nào tôi có thể nhận được xargs để không làm điều này?

Tôi có một công việc hàng loạt 1500 hoặc hơn mà tôi muốn chạy, 50 dòng một lần. Tôi đã thấy rằng nó luôn luôn chết ở một dòng nhất định, và không hoàn thành công việc. Không tốt!

Một câu hỏi thậm chí tốt hơn, câu hỏi mô tả những gì tôi đang cố gắng làm, là:

Làm cách nào tôi có thể chạy một tập lệnh bó 1500 dòng, 50 dòng một lần, để nó không bỏ công việc ở giữa và để đầu ra được ghi vào một tệp nhật ký nào đó?

Câu trả lời:


12

Bạn có thể gói tập lệnh perl bằng một tập lệnh bash đơn giản khác:

#!/bin/bash
real-command "$@" || exit 0

Điều này sẽ gọi lệnh real truyền cho nó tất cả các tham số mà bạn truyền cho lệnh fake này và nó sẽ luôn trả về mã thoát 0 (có nghĩa là nó luôn thành công) và xargs sẽ không bao giờ dừng với điều này.


24

Tương tự như larskscâu trả lời nhưng rõ ràng hơn:

xargs sh -c "somecommand || true"

sử dụng sh -ccho tôi
hukeping

9

Bạn có thể viết lời mời xargs của mình để che dấu mã trả về của dòng lệnh. Với một cái gì đó như sau, xargssẽ không bao giờ thấy mã thoát được trả về bởi somecommand :

xargs sh -c "somecommand || :"

Tôi đã đưa ra một giải pháp tốt: đảm bảo các lệnh đang được xử lý không thoát với trạng thái 255! Chi tiết bổ sung Lệnh đang được xử lý là tập lệnh Perl. Hàm Perl die () đã được sử dụng ở một số nơi để thoát ra nếu xảy ra một số lỗi nghiêm trọng (ví dụ: không thể kết nối với cơ sở dữ liệu). Tuy nhiên, die () luôn thoát với trạng thái lỗi 255. Giải pháp trong trường hợp này là thay die () bằng sự kết hợp giữa in và thoát (), cùng với mã lỗi hợp lý hơn ("1" hoạt động trong trường hợp này).
JDS

6

Chỉ cần tìm một câu trả lời thú vị cho câu hỏi này, mặc dù tính hữu dụng của nó sẽ phụ thuộc vào lệnh bạn đang cố chạy.

Nếu bạn đang sử dụng xargs để cơ bản lắp ráp một danh sách các lệnh, bạn có thể có hành vi này bằng cách yêu cầu xargs lặp lại lệnh, sau đó chuyển sang bash.

Ví dụ: nếu bạn đang cố xóa danh sách những thứ có thể tồn tại hoặc không tồn tại:

# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit

# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash

Điều này hoạt động bởi vì, đầu tiên, xargs chỉ gọi echo, vì vậy nó sẽ không thấy bất kỳ lỗi nào. Sau đó, thứ hai, bởi vì hành vi mặc định của bash để tiếp tục thực hiện sau khi một tuyên bố thất bại.

Để cụ thể hơn về trường hợp của tôi, tôi đã sử dụng điều này để loại bỏ một loạt các phiên bản ứng dụng cũ khỏi AWS ElasticBeanstalk như vậy:

aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
  echo aws elasticbeanstalk delete-application-version \
       --delete-source-bundle --application-name myapp --version-label |\
bash

4

Sau công trình xây dựng cho tôi:

ls | xargs -I % svn upgrade %

Ngay cả khi nâng cấp svn không thành công trên một số phần tử, quá trình vẫn được tiếp tục


3

Nếu bạn đang sử dụng xargsvới find, hãy sử dụng -exectùy chọn findthay thế:

find . -name '*.log' -exec somecommand {} \;

1
hú tôi có thể sử dụng nhưng tùy chọn -exec không song song hóa các hoạt động theo cách sử dụng xargs có thể và thực hiện
JDS

2
Cảm ơn bạn - Tôi không biết rằng xargscó thể chạy các lệnh song song. Mát mẻ. Nếu bạn chỉ muốn giảm thiểu số lượng lệnh, -execcó một +tham số.
Roger Dahl
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.