쉘 스크립트에서는 다음과 같이 여러 파이프를 사용하는 경우가 많습니다.
cmd1 | cmd2 | cmd3
이제 cmd2
파이프가 없으면 "손상"이 발생하고 cmd3
입력이 수신되지 않습니다.
해결 방법으로 cmd2가 존재하는지 명시적으로 테스트할 수 있지만 이를 위해서는 피하고 싶은 일부 코드 중복이 필요합니다.
대신에 다음과 같이 좀 더 간결한 테스트를 원합니다.
cmd1 | cmd2; [ $? -eq 127 ] && cat | cmd3
답변1
더 간결하게 만들기 위해 미니 함수를 작성할 수 있습니다.
ifexists(){
if command -v "$1"
then "$@"
else echo "doing cat for missing $1" >&2
cat
fi
}
echo hi | ifexists mycommand | cat -n
답변2
|
귀하의 예에 따르면 , (예: &&
및 )보다 우선순위가 낮은 ||
작업에 대한 매개변수를 그룹화하는 방법을 찾고 있는 것으로 보입니다 .
{
메타 문자를 }
사용하여 이러한 방식으로 그룹화할 수 있습니다.
위의 예는 다음과 같이 작성할 수 있습니다(종료 상태를 사용하여 존재 which
하는지 확인 cmd2
).
cmd1 | { which cmd2 >/dev/null && cmd2 || cat; } | cmd3
예를 들어
printf "hi\n" | { : && rev || cat; } | cat
인쇄됩니다ih
서브쉘 사용에 대한 귀하의 제안도 작동하지만 불필요하게 다른 프로세스를 사용합니다.
printf "hi\n" | ( : && rev || cat ) | cat
if
파이프 외부에서 명시적을 사용하면 덜 까다롭고 유지 관리가 더 쉬울 수 있다고 말하고 싶습니다 .
if [ which cmd2 >/dev/null ]
then
cmd1 | cmd3
else
cmd1 | cmd2 | cmd3
fi