Bash에서 첫 번째 줄 이후 루프가 읽기를 중지하는 동안
저는 다음과 같은 셸 스크립트를 가지고 있습니다.이 목적은 대상 파일의 각 줄(경로가 스크립트에 대한 입력 매개 변수임)을 루프하고 각 줄에 대해 작업을 수행하는 것입니다.이제 대상 파일의 첫 번째 줄에서만 작동하고 해당 줄이 처리된 후에 중지됩니다.제 대본에 무슨 문제라도 있나요?
#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets
FILENAME=$1
count=0
echo "proceed with $FILENAME"
while read LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done < $FILENAME
echo "\ntotal $count targets"
인do_work.sh
몇 개를 운영하고 있습니다.ssh
명령을 실행합니다.
문제는do_work.sh
달리기ssh
명령 및 기본값ssh
stdin에서 읽습니다. stdin은 입력 파일입니다.결과적으로 명령어가 파일의 나머지 부분을 소비하고 사용 중 루프가 종료되기 때문에 처리된 첫 번째 줄만 표시됩니다.
이것은 단지 때문만은 아닙니다.ssh
하지만 stdin으로 표시된 명령에 대해서는 다음을 포함합니다.mplayer
,ffmpeg
,HandBrakeCLI
,httpie
,brew install
기타 등등.
이를 방지하려면 다음을 통과합니다.-n
에 대한 옵션ssh
에서 읽도록 하는 명령/dev/null
Stdin 대신에.다른 명령에도 유사한 플래그가 있거나 일반적으로 사용할 수 있습니다.< /dev/null
.
매우 간단하고 강력한 해결 방법은 파일 설명자를 변경하는 것입니다.read
명령이 입력을 수신합니다.
이는 두 가지 수정에 의해 달성됩니다.-u
에 대한 주장.read
의 리디렉션 연산자< $FILENAME
.
BASH에서 기본 파일 설명자 값(예:-u
에read
)은 다음과 같습니다.
- 0 = stdin
- 1 = stdout
- 2 = stderr
사용하지 않는 다른 파일 설명자를 선택하십시오. 예를 들어,9
그냥 재미로
따라서 다음과 같은 해결 방법이 있습니다.
while read -u 9 LINE; do
let count++
echo "$count $LINE"
sh ./do_work.sh $LINE
done 9< $FILENAME
두 가지 수정 사항에 유의하십시오.
read
된다read -u 9
< $FILENAME
된다9< $FILENAME
모두를 위해 이 작업을 수행하는 것이 좋습니다.while
내가 BASH로 쓰는 루프.중첩 루프가 있는 경우 다음을 사용합니다.read
각 파일에 대해 서로 다른 파일 설명자(9,8,7,...)를 사용합니다.
보다 일반적으로 특정 문제가 아닌 해결 방법ssh
그렇지 않으면 사용할 수 있는 모든 명령에 대한 표준 입력을 리디렉션하는 것입니다.while
루프의 입력
while read -r line; do
((count++))
echo "$count $line"
sh ./do_work.sh "$line" </dev/null
done < "$filename"
의 추가.</dev/null
여기서 중요한 점은 수정된 인용문이 견고성에도 어느 정도 중요하지만 인용문을 셸 변수로 묶어야 할 때를 참조하십시오.사용할 수 있습니다.read -r
입력에서 백슬래시가 발생할 경우 발생하는 약간 이상한 레거시 동작이 특별히 필요하지 않는 한-r
마지막으로, 개인 변수의 대소문자는 피합니다.
어느 정도 특정한 종류의 다른 해결 방법ssh
확실하게 하기 위해서입니다.ssh
명령에는 표준 입력이 연결되어 있습니다(예: 변경).
ssh otherhost some commands here
. 서는 (이) 합니다. (으)ㄹ 수 있습니다. (으)ㄹ 수 있습니다.ssh
다음 명령의 경우:
ssh otherhost <<'____HERE'
some commands here
____HERE
ssh -n 옵션을 사용하면 다른 프로그램으로 출력을 파이프하는 동안 HEREdoc을 사용할 때 ssh의 종료 상태를 확인할 수 없습니다.따라서 /dev/null을 stdin으로 사용하는 것이 좋습니다.
#!/bin/bash
while read ONELINE ; do
ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm
echo "Hi, $ONELINE. You come here often?"
process_response_pgm
EOF
if [ ${PIPESTATUS[0]} -ne 0 ] ; then
echo "aborting loop"
exit ${PIPESTATUS[0]}
fi
done << input_list.txt
제게 이런 일이 일어난 것은 제가 가지고 있었기 때문입니다.set -e
a 리고a.grep
루프에서 출력 없이 반환되었습니다(0이 아닌 오류 코드 제공).
언급URL : https://stackoverflow.com/questions/13800225/while-loop-stops-reading-after-the-first-line-in-bash
'source' 카테고리의 다른 글
WPF 및 XAML의 숨겨진 기능? (0) | 2023.05.29 |
---|---|
AssemblyVersion, AssemblyFileVersion 및 AssemblyInformationVersion의 차이점은 무엇입니까? (0) | 2023.05.29 |
데이터 프레임의 모든 열에 대해 dtype을 확인하는 방법은 무엇입니까? (0) | 2023.05.29 |
파이썬이 정수 나눗셈을 음의 무한대로 반올림하기로 선택한 수학적 이유는 무엇입니까? (0) | 2023.05.29 |
vb.net 의 목록.각자를 위해 - 나를 혼란스럽게 합니다. (0) | 2023.05.29 |