테스트 프로그램에서 파이프의 값을 어떻게 사용합니까?


10
wc -l | test -eq 1

작동하지 않습니다. wc의 결과를 1의 값과 비교하고 싶습니다. 어떻게 할 수 있습니까?

답변:


9

파이프에 대한 귀하의 질문에 대답하지 않지만 다음과 같이 재정렬 할 수 있습니다.

test $(ls -l | wc -l) -eq 1 && echo "worked"

그리고 SO에 대한 몇 가지 해결책 이 있습니다.

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }

4

Bash를 사용하는 경우 PIPESTATUS 변수를 조사 할 수 있습니다. Bash 참조 가이드 에서 언급했듯이 PIPESTATUS는

가장 최근에 실행 된 포 그라운드 파이프 라인 (단일 명령 만 포함 할 수 있음)의 프로세스에서 종료 상태 값 목록을 포함하는 배열 변수 (배열 참조)

PIPESTATUS를 사용하여이 파이프 라인에 대한 종료 코드가 무엇인지 확인할 수 있습니다.

dmesg | grep -iw 'nnse' | wc -l

이제 배열 변수를 쿼리하면 파이프 라인에 사용 된 명령을 참조하여 종료 상태를 얻습니다.

echo ${PIPESTATUS[@]}
0 1 0

(인덱싱 된 배열에서 배열은 항상 Bash에서 0에서 시작하므로 위의 종료 코드는 배열에서 0 1 및 2로 표시됩니다.)

여기에서 두 번째 명령은 1을 반환하고 나머지는 0을 반환합니다. 그러나 wc -l0이 일치하지 않으면 0을 반환하는데 이는 오류가 아닙니다. 실패는 0이 아닌 값으로 표시되며 명령을 찾을 수없는 127과 같은 다른 오류 값과 관련 프로그램에 고유 한 더 많은 코드가 있습니다.

파이프 라인에서 특정 명령의 종료 코드가 무엇인지 보려면 해당 값에 액세스하면됩니다. grep 명령은 위의 파이프 라인에서 두 번째 명령 이었지만 배열이 0에서 시작하면 항목 1이 필요합니다.

따라서 grep 명령의 종료 코드를 찾으려면 위 파이프 라인을 다시 실행하고 (실행 한 경우 PIPESTATUS의 내용이 소진되었으므로 echo ${PIPESTATUS[@]}) 아래 명령을 실행하면 1 (종료 코드)이 리턴됩니다.

echo ${PIPESTATUS[1]}
1

스크립트에서 PIPESTATUS 배열 변수의 내용을 찾기 전에 파이프 라인의 실행이 완료되었는지 확인하십시오.

PIPESTATUS 배열 변수를 흥미롭게 사용하는 예는 Bash 명령 그룹화와 파이프 상태 결합에 대한 이 답변을 참조하십시오 . 주석에서 Gilles가 제안한 방식으로 배열 변수를 테스트 할 수 있지만 먼저 파이프 라인을 다시 실행해야합니다.

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

어떤 종류의 스크립트를 사용하는지 모르기 때문에 PIPESTATUS에 대해 아는 것이 도움이되기를 바랍니다. PIPESTATUS와 같이 매우 유용한 Bash 배열 변수가 많이 있습니다. 전체 목록 은 Bash 참조 안내서 와 사용법에 대한 다른 Stackexchange 사이트를 참조 하십시오 .


2

가장 간단한 방법은 아마도 xargs 를 사용하는 것입니다 .

wc -l | xargs -I % test % -eq 1

1

이것은 모든 커버하지 않는 test경우가 있지만, 정규 표현식, 사용할 수있는 경우 grep, 파이프로 연결된 문자열을하기 때문에, 그것은 꽤 똑바로 앞으로의 grep입니다 test일치하는 항목이없는 경우는 0이 아닌 종료를 갖는 것을 -like

cat file | wc -l | grep -qE '^\s*1\s*$'

확장 정규 표현식을 사용하면이 기술로 많은 경우를 처리 할 수 ​​있습니다. 낄낄 거림 테스트 케이스 :

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s*$'; then 
    echo "'$i' matched"
  else
    echo "'$i' didn't match."
  fi
done

출력 :

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.