나는 보통 if [ -t 0 ]
stdin을 테스트하고 if [ -t 1 ]
stdin과 stdout이 TTY인지 확인하는 데 사용하며 그렇지 않은 경우 파이프라고 가정합니다. 나는 최근에 그것이 나쁜 가정이라는 것을 알게되었습니다.
function context()
{
if [ -t 0 ]
then
if [ -t 1 ]
then
echo "no pipes"
else
echo "pipe out only"
fi
else
if [ -t 1 ]
then
echo "pipe in only"
else
echo "pipe in and out"
fi
fi
}
echo "No Loop:" # these cases work as desired
context
echo 'f' | context
echo 'f' | context | cat
context | cat
echo
echo "Loop:"
echo $'foo
bar' | while read x
do
context # I want this to say "no pipes"
echo 'f' | context
done
위 bash의 출력은 다음과 같습니다.
No Loop:
no pipes
pipe in only
pipe in and out
pipe out only
Loop:
pipe in only
pipe in only
pipe in only
pipe in only
context
5 번째 및 7 번째 호출이 "no pipes"를 인쇄하도록 to 의 정의를 어떻게 변경할 수 있습니까?
즉, stdin이 터미널이 아닌지 테스트하기보다 (문제를 일으키는)이 특정 함수에 대한 stdin이 파이프인지 테스트하고 싶습니다. -p
이름이 지정된 파이프인지 확인하는 것을 확인했지만 익명 파이프를 위해 이것을 원합니다.
편집하다
실제 사용 사례에는 theDb
대신 호출 할 함수가 포함됩니다 context
. 이상적으로 아래의 두 경우는 컨텍스트에 관계없이 동일합니다.
cat file_with_some_sql | theDb
theDb "sql goes here"
"파이프 인 전용" 이 네 번 나타나는 이유 는 실제로 context
함수가 올바르게 작동하고 있고 echo $'foo bar' | while read x
등 이 파이프 이기 때문 입니다. 루프의 모든 것이 파이프 에서 while
입력을 받고 있기 때문 입니다. 원하는 출력을 얻으려면 while
루프를 루프로 변경하고 해당 루프에 for
아무것도 파이프하지 마십시오 for
.
for x in foo bar; do context ; echo 'f' | context; done
산출:
no pipes
pipe in only
no pipes
pipe in only
OP 코드가 어디에서 잘못되었는지 표시하려면 for
루프에 무언가를 파이프하고 어떤 일이 발생하는지 확인하십시오.
echo | for x in foo bar; do context ; echo 'f' | context; done
산출:
pipe in only
pipe in only
pipe in only
pipe in only
초보자 while read x
는 표준 입력을 모두 소비 한다고 (잘못) 생각할 수 있지만 반드시 그런 것은 아닙니다. 루프 read
내부에 다음 예제를 고려하십시오 while
.
printf '%s\n' foo bar baz buzz |
while read x; do echo $x; read y; echo ${y^^} ;done
산출:
foo
BAR
baz
BUZZ
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다