단일 파이프 명령에 대한 파이프 오류 설정


18

다음과 같이 BASH 이외의 스크립트 (PHP 스크립트)에서 여러 파이프 쉘 명령을 실행해야합니다.

command1 | command2 | command3

따라서 command10이 아닌 종료 코드로 실패하면 서로 명령이 실패합니다. 지금까지 내가 생각해 낸 것은 다음과 같습니다.

set -o pipefail && command1 | command2 | command3

그러나 터미널에서 제대로 실행되지만 스크립트에서 실행하면 다음과 같이 생성됩니다.

sh : 1 : 설정 : 잘못된 옵션 -o pipefail


그가 나타납니다 /bin/sh좋아하지 않는다 set -o pipefail. 실제로 bash변장입니까, 아니면 다른 껍질입니까? bash로 실행 되면 /bin/sh수락 set -o pipefail합니까?
Jonathan Leffler

@JonathanLeffler 내가 실행할 때 (와 같은 것 )이 /bin/sh set -o pipefail말합니다 . 내가 올바르게 테스트했으면 좋겠다. 시스템은 우분투 12입니다./bin/sh: 0: Can't open setsudo
Desmond Hume

시도해야합니다 /bin/sh -c "set -o pipefail"; 셸은 현재 디렉토리에서 스크립트를 실행하려고 set했으나 찾지 못했습니다.
Jonathan Leffler

@JonathanLeffler /bin/sh -c "set -o pipefail"는 작동 bash -c "set -o pipefail"하지 않습니다.
Desmond Hume

따라서 문제는 스크립트를 /bin/sh인식하지 못하는 스크립트가 실행된다는 것 입니다 set -o pipefail. 결과적으로 스크립트 /bin/bash대신에 스크립트가 실행되도록해야합니다 /bin/sh. 또는 확신이 있다면 용감하고 어리석은 사람 은 현재 연결된 쉘 /bin/sh이나 사본 /bin/bash대신 링크 또는 사본으로 변경됩니다. 당신이 만약하고 있는지 확인 /bin/sh입니다 bash, 당신은 행동을 사용하고 bash로 실행할 때 노출하지 않습니다 /bin/sh; 사용 bash으로 bash.
Jonathan Leffler

답변:


18

Bash 명령 행에서 pipefail이후에 설정 되지 않도록 서브 쉘을 호출해야합니다 .

$ (set -o pipefail && command1 | command2 | command3)

이것은 pipefail옵션 의 효과를 괄호로 작성된 서브 쉘로 제한합니다 (...).

실제 예 :

$ (set -o pipefail && false | true) && echo pipefail inactive || echo pipefail active
pipefail active

-c옵션 과 함께 명시적인 쉘 호출을 사용하는 경우 다음 과 같이 bash또는 sh별명 과 함께 서브 쉘이 필요하지 않습니다 bash.

$ bash -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active
$ sh -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active

귀하 shpipefail옵션을 수락하지 않기 때문에 이전 버전 또는 수정 된 버전 bash이거나 실제로 다른 쉘 이라고 가정해야합니다 .


1
$명령의 일부는 그냥 쉘 프롬프트 첫 번째 조각인가? 두 가지 방법을 모두 시도했지만 실제로 작동하지 않았습니다. 그 bash -c방법은 항상 너무 우아하지 않은 방식으로 작동합니다.
Desmond Hume

5

왜 위에서 언급되지 않았는지 모르지만을 pipefail사용하여 명시 적으로 설정 해제 할 수 있습니다 set +o pipefail.

set -o pipefail
command1 | command2 | command3
set +o pipefail

프래그먼트를 실행하고 pipefail이미 설정되어 있는지 확실하지 않은 경우 이전에 제안한대로 서브 쉘과 함께이를 사용할 수 있습니다.

# explicitly execute with pipefail set
(set -o pipefail ; command1 | command2 | command3 )
# explicitly execute with pipefail unset
(set +o pipefail ; command1 | command2 | command3 )

0

$ (command1)을 $와 결합하여 사용할 수 있습니까? :

a=$(echo "a")
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

"abc"인쇄

a=$(ls unexitingDir)
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

""를 인쇄합니다.

"[$? -eq 0] &&"는 다음 명령이 이전 명령이 성공한 경우에만 실행됨을 의미합니다.

그것은 당신의 질문에 대답하지 않지만 그것은 당신의 문제에 대한 해결책입니다.


그것은 항상 각 명령의 출력을 변수에 저장해야한다는 것을 의미합니까?
데스몬드 ume

항상 모르겠지만 솔루션을 사용하면 다음 명령에 필요한 경우 예입니다. 당신이 그냥 쓸 수 없다면command1 && command2 && command3
cglacet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.