source

Bash에서 첫 번째 줄 이후 루프가 읽기를 중지하는 동안

factcode 2023. 5. 29. 11:12
반응형

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명령 및 기본값sshstdin에서 읽습니다. stdin은 입력 파일입니다.결과적으로 명령어가 파일의 나머지 부분을 소비하고 사용 중 루프가 종료되기 때문에 처리된 첫 번째 줄만 표시됩니다.

이것은 단지 때문만은 아닙니다.ssh하지만 stdin으로 표시된 명령에 대해서는 다음을 포함합니다.mplayer,ffmpeg,HandBrakeCLI,httpie,brew install기타 등등.

이를 방지하려면 다음을 통과합니다.-n에 대한 옵션ssh에서 읽도록 하는 명령/dev/nullStdin 대신에.다른 명령에도 유사한 플래그가 있거나 일반적으로 사용할 수 있습니다.< /dev/null.

매우 간단하고 강력한 해결 방법은 파일 설명자를 변경하는 것입니다.read명령이 입력을 수신합니다.

이는 두 가지 수정에 의해 달성됩니다.-u에 대한 주장.read의 리디렉션 연산자< $FILENAME.

BASH에서 기본 파일 설명자 값(예:-uread)은 다음과 같습니다.

  • 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

두 가지 수정 사항에 유의하십시오.

  1. read된다read -u 9
  2. < $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

반응형