오류시 xargs가 종료되지 않도록 방지


27

매뉴얼 페이지에 따르면, 실행 행 중 하나가 오류 255로 종료되면 xargs가 종료됩니다.

명령 호출이 255 상태로 종료되면 xargs는 추가 입력을 읽지 않고 즉시 중지됩니다. 이 경우 stderr에 오류 메시지가 발행됩니다.

xargs 가 이것을 하지 않도록하려면 어떻게해야합니까?

한 번에 50 줄씩 1500 줄 정도의 배치 작업을 실행하려고합니다. 나는 그것이 특정 라인에서 항상 죽어 가고 있었고 일을 끝내지 않았다는 것을 알았습니다. 안좋다!

더 나은 질문, 내가하려는 일을 설명하는 질문은 다음과 같습니다.

1500 줄 배치 스크립트를 한 번에 50 줄씩 실행하여 중간에 작업을 종료하지 않고 출력이 어떤 종류의 로그 파일로 캡처되도록하려면 어떻게해야합니까?

답변:


12

다른 간단한 bash 스크립트로 perl 스크립트를 감쌀 수 있습니다.

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

이것은 실제 명령 을 호출 하여이 가짜 명령에 전달하는 모든 매개 변수를 전달하고 항상 0 종료 코드를 반환합니다 (즉, 항상 성공 함). xargs는이로 멈추지 않습니다.



9

명령 행의 리턴 코드를 마스크하기 위해 xargs 호출을 작성할 수 있습니다. 다음과 같은 경우 xargs종료 명령이 somecommand에 의해 반환되는 것을 볼 수 없습니다 .

xargs sh -c "somecommand || :"

나는 좋은 해결책을 생각해 냈습니다 : 처리중인 명령이 255 상태로 종료되지 않도록하십시오! 추가 세부 사항 처리중인 명령은 Perl 스크립트입니다. Perl die () 함수는 심각한 오류가 발생한 경우 (예 : 데이터베이스에 연결할 수없는 경우) 종료하기 위해 여러 곳에서 사용되었습니다. 그러나 die ()는 항상 오류 상태 255로 종료됩니다.이 경우 해결책은보다 합리적인 오류 코드 (이 경우 "1")와 함께 die ()를 print와 exit ()의 조합으로 바꾸는 것입니다.
JDS

6

이것에 대한 재미있는 답변을 찾았지만 유용성은 실행하려는 명령에 달려 있습니다.

xargs를 사용하여 기본적으로 명령 목록을 어셈블하는 경우 xargs에 명령을 에코 한 다음 bash로 파이핑하여이 동작을 수행 할 수 있습니다.

예를 들어, 존재하거나 존재하지 않는 것의 목록을 삭제하려는 경우 :

# 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

xargs는 항상 에코 만 호출하므로 오류가 발생하지 않기 때문에 작동합니다. 두 번째로, bash의 기본 동작이 실패한 명령문 후에 실행을 계속하기 때문입니다.

필자의 경우에 대해 더 구체적으로 설명하기 위해 AWS ElasticBeanstalk에서 오래된 애플리케이션 버전을 제거하는 데 사용했습니다.

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

다음과 같은 공사가 나를 위해 일합니다.

ls | xargs -I % svn upgrade %

일부 요소에서 svn 업그레이드가 실패한 경우에도 프로세스가 계속되었습니다


3

사용 된 경우 xargsfind, 사용 -exec의 옵션 find을 대신 :

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

1
Howdy. 나는 그것을 사용할 수 있지만 -exec 옵션은 xargs를 사용하는 방식과 동작을 병렬화하지 않습니다.
JDS

2
고맙습니다- xargs명령을 병렬로 실행할 수 있다는 것을 몰랐습니다 . 시원한. 당신은 단지 명령 호출의 수를 최소화하려면, -exec+매개 변수를.
Roger Dahl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.