한 프로세스에서 다른 프로세스로 출력을 파이프하지만 첫 번째 출력이있는 경우에만 실행하는 방법은 무엇입니까? 출력이있는 경우 전자

에서 출력이있는 경우 전자 메일로만이 명령을 다시 작성하려면 mailq | grep어떻게 해야 합니까?

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email

한 줄로도 가능합니까?

이메일을 보내는 것보다 일반적인 경우 가 아닌 경우 파이프가 비어 있는지 확인하고 데이터에서 명령 실행을 참조 하십시오 .



답변

&&grep이 다음과 일치하는 종료 상태를 리턴 한 경우 연산자를 사용 하여 mail 명령 만 실행할 수 있도록이 조작에 임시 파일을 사용해야한다고 생각합니다 .

TMPFILE=`mktemp /tmp/mailqgrep.XXXXXX`; mailq | egrep 'rejected|refused' -A5 -B5 > "$TMPFILE" && mail -s 'dd' email@email < "$TMPFILE"; rm "$TMPFILE"

임시 파일이 어딘가에 붙어 있고 정적 이름을 사용할 수 없다면 특별한 이름 지정 및 삭제 항목을 건너 뛸 수 있습니다.

 mailq | egrep 'rejected|refused' -A5 -B5 > /tmp/mailqgrep && mail -s 'dd' email@email < /tmp/mailqgrep

편집 : glenn의 대답을 본 후에이 부분을 더 연주하고 $()구문을 사용하여 변수를 할당 하면 명령의 종료 코드가 반환되므로 문자열 길이에 사용한 테스트를 건너 뛰고 대신 사용할 수 있습니다. 여기에 하나의 명령이 있습니다.

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5) && mail -s 'dd' email@email <<< "$data"

편집 2 : Simon의 답변을 본 후 mail프로그램을 확인했습니다 . 기본적으로 설명 된 방식으로 작동하지 않지만 이에 대한 옵션이 있습니다. 매뉴얼 페이지에서 :

-E발신 메시지의 첫 번째 또는 유일한 메시지 부분에 텍스트가 포함되어 있지 않으면 메시지를 보내지 말고 자동으로 삭제하여 프로그램 시작시 skipemptybody 변수를 효과적으로 설정하십시오. cron (8)으로 시작된 스크립트에서 메시지를 보내는 데 유용합니다.

가능하게하기 :

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -E -s 'dd' email@email

답변

유틸리티 프로그램 ifne 은이 목적을 위해 명시 적으로 존재합니다. 표준 입력이 비어 있지 않은 경우 명령을 실행합니다.

mailq | egrep 'rejected|refused' -A 5 -B 5 | ifne mail -s 'dd' email@email

ifne 명령은 moreutils 패키지의 일부이며 “유닉스가 어렸을 때 아무도 오래 전에 생각하지 않은 유닉스 도구 모음”으로 표시됩니다.


답변

출력을 변수에 저장 한 다음 문자열 길이가 0이 아닌 경우 mail 명령을 호출 할 수 있습니다.

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5)
[[ -n "$data" ]] && mail -s 'dd' email@email <<< "$data"

한 줄의 경우 두 명령을 세미콜론으로 연결하십시오.


답변

옵션 mail과 함께 사용하십시오 -E. 내 Mac에서 MAIL (1)은 -E깃발이 비어있는 이메일을 보내지 않을 것이라고 말합니다 .

-E 본문이 비어있는 메시지를 보내지 마십시오. 이것은 cron (8) 스크립트에서 파이핑 오류에 유용합니다.

내 Mac에서 다음 테스트를 실행했습니다. 파일 file_does_exist은 존재하지만 파일 은 존재 file_does__not_exist하지 않습니다.

이것은 나에게 이메일을 보냅니다 :

$ ls file_does_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org

그렇지 않습니다. 명령 ls file_does_not_exist | egrep ...은 출력을 생성하지 않습니다.

$ ls file_does_not_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org
ls: file_does_not_exist: No such file or directory

답변

이 특별한 경우, 옵션을 지원하는 경우mail-E 사용하십시오. 일반적인 경우 한 문자를 읽으려고 시도 할 수 있습니다. 있는 경우 사후 처리 명령을 시작하고 파일의 나머지 부분에서 해당 문자를 제공하십시오.

pipe_if_not_empty () {
  a=$(dd bs=1 count=1 2>/dev/null; echo .)  # read at most one character
  if [ "$a" != "." ]; then                  # if there were two characters,
    { printf %s "${a%.}";                   # then output the first character
      cat; } |                              # and the rest of the input   
    "$@"                                    # into the specified program
  fi
}

mailq | egrep 'rejected|refused' -A 5 -B 5 |
pipe_if_not_empty mail -s 'dd' email@email

의 유용한 사용법에 유의하십시오 cat. 추가 echo .하면 입력의 첫 번째 문자가 줄 바꿈 인 경우에도이 함수가 작동합니다 ( $(…)구문 이 줄 바꿈을 제거함을 기억하십시오 ).

대부분의 쉘 (내가 아는 한 zsh 이외의 것)에서 파일이 null 문자로 시작하면이 코드는 비어 있다고 믿습니다. 독자를위한 연습으로 남겨진 고정. (힌트 : od첫 번째 서브 쉘에서 사용 printf하고 첫 번째 바이트를 인쇄합니다.) (해결 방법 : 파이프가 비어 있는지 확인하는 방법 ) 파일이 현재 문자가 아닌 바이트로 시작하면 같은 문제가 발생할 수 있습니다. 장소; 로이 코드를 실행하면 쉽게 해결할 수 LC_ALL=C있습니다.


답변

mail빈 메시지가 표시되면 IIRC BSD 명령이 중단됩니다.


답변

최근 ifne에는 moreutils패키지의 일부인 명령 이름에 대해 배웠습니다 . 이 특정 문제를 해결하기 위해 사용할 수있는 곳.

ifne- 표준 입력이 비어 있지 않은 경우 명령 실행

맨 페이지의 예

EXAMPLE
       find . -name core | ifne mail -s "Core files found" root