첫 번째 반복 후에 이 while 루프가 종료되는 이유는 무엇입니까?

첫 번째 반복 후에 이 while 루프가 종료되는 이유는 무엇입니까?

while 루프에서 특정 도구(NCBI Electronics Utility Suite의)를 사용하려고 시도하는 esearch동안 매우 이상한 상황에 직면했습니다 . 이것은 한 줄에 하나씩 문자열 목록인 입력 파일입니다.

$ cat transcripts.list 
NR_169596.1
NR_169595.1
NR_169594.1

각 문자열을 인수로 사용하여 명령을 실행 하고 싶으 esearch므로 다음과 같이 합니다.

$ while read -r line; do echo "Line: $line"; esearch -db nucleotide -query "$line"; done <  transcripts.list 
Line: NR_169596.1
<ENTREZ_DIRECT>
  <Db>nucleotide</Db>
  <WebEnv>MCID_61bb689d20b59b3e2e2d405d</WebEnv>
  <QueryKey>1</QueryKey>
  <Count>1</Count>
  <Step>1</Step>
</ENTREZ_DIRECT>

echo단일 결과를 실행하여 볼 수 있듯이 이는 세 개가 아닌 하나의 결과입니다 . 그러나 내가 사용하면나쁜 습관 for반지:

$ for line in $(cat transcripts.list); do echo "Line: $line"; esearch -db nucleotide -query "$line"; done
Line: NR_169596.1
<ENTREZ_DIRECT>
  <Db>nucleotide</Db>
  <WebEnv>MCID_61bb68cabbe98560233344a7</WebEnv>
  <QueryKey>1</QueryKey>
  <Count>1</Count>
  <Step>1</Step>
</ENTREZ_DIRECT>
Line: NR_169595.1
<ENTREZ_DIRECT>
  <Db>nucleotide</Db>
  <WebEnv>MCID_61bb68cad05f5825d75e3ace</WebEnv>
  <QueryKey>1</QueryKey>
  <Count>1</Count>
  <Step>1</Step>
</ENTREZ_DIRECT>
Line: NR_169594.1
<ENTREZ_DIRECT>
  <Db>nucleotide</Db>
  <WebEnv>MCID_61bb68cb6bdec5435b5a41cb</WebEnv>
  <QueryKey>1</QueryKey>
  <Count>1</Count>
  <Step>1</Step>
</ENTREZ_DIRECT>

질문:어떻게 이럴 수있어? 특정 프로그램에 어떤 종류의 버그가 있더라도 esearch루프에 영향을 주어서는 안 되는데 왜 첫 번째 반복 후에 쉘이 종료됩니까? for일은 어떻게 while실패할 수 있나요? 여기서 그들은 무엇을 다르게 하고 있나요?


자세한 내용은.

  1. esearch 명령 앞에 추가하면 echo루프가 예상대로 작동하므로 이는 esearch특정 명령과 관련되어야 합니다(그러나 이것이 어떻게 쉘 루프를 중단합니까?).

    $ while read -r line; do echo esearch -db nucleotide -query "$line"; done <  transcripts.list 
    esearch -db nucleotide -query NR_169596.1
    esearch -db nucleotide -query NR_169595.1
    esearch -db nucleotide -query NR_169594.1
    
  2. 목록 자체에는 이상한 점이 없습니다. 숨겨진 문자 없이 다른 목록으로 재현할 수 있습니다.

    $ od -c transcripts.list 
    0000000   N   R   _   1   6   9   5   9   6   .   1  \n   N   R   _   1
    0000020   6   9   5   9   5   .   1  \n   N   R   _   1   6   9   5   9
    0000040   4   .   1  \n
    0000044
    
  3. Bash와 Dash에서 동일한 동작이 발생하므로 PIPEFAIL 또는 이와 유사한 것과 관련될 수 없습니다. 이 명령의 종료 상태는 무슨 일이 있어도 0입니다.

     while read -r line; do esearch -db nucleotide -query "$line"; echo "EXIT: $?"; done <  transcripts.list 
    <ENTREZ_DIRECT>
      <Db>nucleotide</Db>
      <WebEnv>MCID_61bb69e71191d1185543b24a</WebEnv>
      <QueryKey>1</QueryKey>
      <Count>1</Count>
      <Step>1</Step>
    </ENTREZ_DIRECT>
    
  4. 이는 Ubuntu, bash, 버전 4.4.20(1) 릴리스를 실행하는 시스템에서 발생합니다. 한번 사용해 보고 싶다면 를 efetch사용하여 도구를 설치할 수 있습니다.sudo apt install ncbi-entrez-direct

  5. 루프에서 다른 언어를 사용하면 예상대로 작동합니다. 예를 들면 다음과 같습니다 perl.

    $ perl -ne 'chomp;system("esearch -db nucleotide -query \"$_\"")' transcripts.list 
    <ENTREZ_DIRECT>
      <Db>nucleotide</Db>
      <WebEnv>MCID_61bb6c68d8f66e4bb03f00e8</WebEnv>
      <QueryKey>1</QueryKey>
      <Count>1</Count>
      <Step>1</Step>
    </ENTREZ_DIRECT>
    <ENTREZ_DIRECT>
      <Db>nucleotide</Db>
      <WebEnv>MCID_61bb6c69947ca95fce4d4f0f</WebEnv>
      <QueryKey>1</QueryKey>
      <Count>1</Count>
      <Step>1</Step>
    </ENTREZ_DIRECT>
    <ENTREZ_DIRECT>
      <Db>nucleotide</Db>
      <WebEnv>MCID_61bb6c6a85c14642940393f9</WebEnv>
      <QueryKey>1</QueryKey>
      <Count>1</Count>
      <Step>1</Step>
    </ENTREZ_DIRECT>
    

답변1

이는 아마도 esearch표준 입력이 모두 소모되었기 때문일 것입니다. read둘 다 esearch읽고 있습니다 transcripts.list.

이 문제를 해결하려면 esearch표준 입력을 다음으로 변경하십시오.예를 들어 esearch < /dev/null.

바라보다파일을 한 줄씩 읽고 ssh 또는 ffmpeg를 실행하면 첫 번째 줄만 처리됩니다!자세한 내용은 Bash FAQ를 참조하세요.

관련 정보