ProgramingTip

입력이 일치하지 않을 때 grep이 오류를 반환하지 않습니다.

bestdevel 2020. 12. 1. 19:10
반응형

입력이 일치하지 않을 때 grep이 오류를 반환하지 않습니다.


프로그램이 이미 실행 중인지 확인하는 코드를 bash 펼쳐서 작성하고 싶습니다. 바가 실행 중인지 검색 결과 다음이 있습니다.

 foo=`ps -ef | grep bar | grep -v grep`

그만큼

 grep -v grep

부분은 ps 결과에서 "grep bar"가 고려하지 않는 것입니다.

bar가 실행되지 않는 곳은 foo는 곳에서 비어 있습니다. 하지만 내 문제는 대본이

 set -e

일부 명령이 오류를 반환하면 종료하는 플래그입니다. bar가 실행되지 않을 때 "grep -v grep"는 아무것도 일치하지 않습니다. 나는 -q 또는 -s를 누르지 만 아무 소용이 없었다.

어디에 있습니까? 고마워


확실한 :

ps -ef | grep bar | { grep -v grep || true; }

또는 :

ps -ef | grep bar | grep -v grep | cat

피해야 할 좋은 트릭 은 다음과 좋은 트릭 grep -v grep.

ps -ef | grep '[b]ar'

해당 정규식은 "bar"와만 일치합니다. 그러나 ps출력에서 "bar"문자열은 grep 프로세스와 함께


에 대해 배우기 며칠 전에 pgrep위의 명령을 자동화하기 위해 함수를 작성했습니다.

psg () { 
    local -a patterns=()
    (( $# == 0 )) && set -- $USER
    for arg do
        patterns+=("-e" "[${arg:0:1}]${arg:1}")
    done
    ps -ef | grep "${patterns[@]}"
}

그때,

psg foo bar

로 변하다

ps -ef | grep -e '[f]oo' -e '[b]ar'

99 % 만 버릴 경우 ps엄청난 양의 출력을 제공 하도록 -ef안내 받았습니까? ps특히 GNU 버전은 편리한 기능의 스위스 군용 칼입니다. 이 시도 :

ps -C bar -o pid= 1>/dev/null

나는 -o pid=여기에 단지 왜냐하면 우리가 어쨌든 모든 stdout을 버리기 때문에 의미가 없습니다. 하지만 실제 실행중인 PID를 알고 있고 유용 할 것입니다.

ps-C일치하지 않고 0이 아닌 존재 상태로 자동으로 반환 되고 일치하면 0으로 반환됩니다. 그래서 말할 수 있습니다.

ps -C bar 1>/dev/null && echo bar running || echo bar not running

또는

if ps -C bar 1>/dev/null ; then
    echo bar running
else
    echo bar not running
fi

더 간단하지 않나요? 두 번 또는 한 번도 grep이 필요하지 않습니다.


짧은 답변

쓰다

ps -ef | grep bar | { grep -v grep || test $? = 1; }

당신이 사용하는 경우 .set -e

bash의 옵션 ( ) 을 사용하는 경우 파이프 라인의 모든 항목 예외 처리 ( )를 적용해야합니다 .

pipefailset -o pipefail||testgrep

ps -ef | { grep bar || test $? = 1; } | { grep -v grep || test $? = 1; }

쉘 펼쳐 에서는 "catch-1-grep" (c1grep) 유틸리티 함수 를 사용하는 것이 좋습니다.

c1grep() { grep "$@" || test $? = 1; }

설명

grep의 종료 상태는 0, 1 또는 2입니다. [1]

  • 0 선이 선택 의미합니다.
  • 1 선택 줄이 없음을 의미합니다.
  • 2 오류가 발생했음을 의미합니다.

grep신호에 의해 중단 된 경우 (예 : 130SIGINT 의 경우) 다른 코드를 반환 할 수도 있습니다 .

exit status 만 무시하고 싶기 때문에 특정 종료 상태를 억제하는 데 1사용 test합니다.

  • 경우 grep반환 0, test실행되지 않습니다.
  • 경우 grep반환 1, test실행 및 반환됩니다 0.
  • 만약 grep다른 값이 반환 test실행 돌아갑니다 1.

마지막 경우에는 set -e또는 로 인해 스크립트가 즉시 종료됩니다 set -o pipefail. 그러나 grep오류에 대해 전혀 신경 쓰지 않는다면 물론 다음과 같이 작성할 수 있습니다.

ps -ef | grep bar | { grep -v grep || true; }

Sean이 제안한대로 .


[추가] 쉘 스크립트에서의 사용법

쉘 스크립트에서 grep많이 사용 하는 경우 유틸리티 함수를 정의하는 것이 좋습니다.

# "catch exit status 1" grep wrapper
c1grep() { grep "$@" || test $? = 1; }

당신의 파이프의 특징을 잃지 않고, 다시 짧은 및 간단한 얻을 것이다이 방법 set -eset -o pipefail:

ps -ef | c1grep bar | c1grep -v grep

참고 :

  • 나는 그것이 c1grep단순히 출구 상태를 잡는다는 것을 강조하기 위해 그것을 불렀다 1.
  • grep대신 함수 ( grep() { env grep "$@" ...; })를 호출 할 수 있지만 덜 혼란스럽고 더 명확한 이름 인 c1grep.

[1] grep맨 페이지


foo=`ps -ef | grep bar | grep -v grep` || true

그렇게하려고 :

ps auxw | grep -v grep | 고양이

cat은 항상 0을 반환하고 grep의 종료 코드를 무시합니다.

참고 URL : https://stackoverflow.com/questions/6550484/prevent-grep-returning-an-error-when-input-doesnt-match

반응형