답변:
다음 ifnotempty
함수는 입력이 비어 있으면 아무것도하지 않는 것을 제외하고 인수로 전달 된 명령에 입력을 파이프합니다. 을 써서 파이프에 source --foo
연결 하십시오 .sink --bar
source --foo | pipe_if_not_empty sink --bar
pipe_if_not_empty () {
head=$(dd bs=1 count=1 2>/dev/null; echo a)
head=${head%a}
if [ "x$head" != x"" ]; then
{ printf %s "$head"; cat; } | "$@"
fi
}
디자인 노트 :
dd
하지는 않습니다. 표준 입력에서 읽도록 지시 된 1 바이트 이상을 읽지 않아야합니다.head -c 1
에서 적합한 대안 이라고 생각 dd bs=1 count=1 2>/dev/null
합니다.head -n 1
있기 때문에 적합하지 않으며 head
파이프에서 읽으므로 여분의 바이트가 손실됩니다.read -r head
심지어 read -r -n 1 head
첫 번째 문자가 개행 인 경우, 때문에 여기에 적합하지 않은 head
빈 문자열로 설정됩니다 빈 라인으로 시작하는 빈 입력과 입력을 구별 할 수 없도록.head=$(head -c 1)
첫 번째 문자가 줄 바꿈이면 명령 대체가 마지막 줄 바꿈을 제거하여 빈 줄과 빈 줄로 시작하는 입력을 구분할 수 없으므로 쓸 수 없습니다 .cat
을 </dev/stdin
위해 대체 할 수 있습니다 .전체 중간 데이터를 메모리에 저장하는 것이 마음에 들지 않으면 여기에 매우 간단한 구현이 pipe_if_not_empty
있습니다.
pipe_if_not_empty () {
input=$(cat; echo a);
if [ "x$input" != x"a" ]; then
{ printf %s "${input%a}"; } | "$@"
fi
}
다음과 같은 경고를 사용하여 약간 더 간단한 구현이 있습니다.
다시, 전체 데이터는 메모리에 저장됩니다.
pipe_if_not_empty () {
input=$(cat);
if [ "x$input" != x"" ]; then
{ printf '%s\n' "${input}"; } | "$@"
fi
}
이것은 당신을 위해 작동합니다
$ --a function-- | [ xargs -r ] --another function--
예
$ echo -e "\n\n" | xargs -r ls
$ # No output. ls did not run.
$ echo -e "\n\n1" | xargs -r ls
ls: cannot access 1: No such file or directory
간단하지만 그것은 당신을 위해 작동합니다. "함수"가 빈 문자열을 보내거나 파이프 라인 아래로 줄 바꿈을 보내면 xargs -r은 "다른 기능"으로 전달되지 않습니다.
xargs에 대한 참조 : http://www.oreillynet.com/linux/cmd/cmd.csp?path=x/xargs
-r, --no-run-if-empty
Do not run command if standard input contains only blanks.
ifne (1) 에서 moreutils는 정확히 않습니다. Moreutils는 최소한 데비안과 우분투, 다른 배포판에서도 패키지로 제공됩니다.
아래 함수는 첫 번째 바이트를 읽으려고 시도하고 성공하면 해당 바이트를 에코하고 나머지는 고양이로 만듭니다. 효율적이고 100 % 휴대 가능해야합니다.
if_read() {
IFS="" read -rN 1 BYTE && { echo -nE "$BYTE"; cat; } | "$@";
}
테스트 사례 :
$ echo -n | if_read wc -c
$ echo | if_read wc -c
1
$ echo -en "\nX" | if_read wc -c
2
$
echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" foo@bar.com
. 그것은 생각 line
하고 here
있지 주제에 토큰, 전자 메일의 모두받는 사람입니다. 나는 "
그 주제를 둘러보기 위해 피해야한다 . 그러나 pipe_if_not_empty
수락 된 답변 의 기능은 아무것도 탈출하지 않아도 나에게 효과적입니다.
적어도 이런 식으로 작동합니다 :
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
위의 내용은 줄 바꿈 및 기타 특수 문자를 출력으로 간주하므로 if 문에 빈 줄이 전달되면 출력으로 간주됩니다. 출력이 보통 1 바이트보다 높아야하는 경우 -gt 제한을 늘리십시오. :)
yourothercommand
의 출력을 보지 못합니다 yourcommand
.
대신 sender | receiver
:
tester () { local a=$(</dev/stdin); if [[ $a ]]; then printf '%s\n' "$a" | receiver; fi; }
sender | tester
또는 Gilles의 답변에서와 같이 수신 프로그램을 인수로 수락하도록 변경하여보다 일반적인 목적으로 만들 수 있습니다.
tester () { local a=$(</dev/stdin); if [[ $a ]]; then printf '%s\n' "$a" | "$@"; fi; }
sender | tester receiver