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
실패할 수 있나요? 여기서 그들은 무엇을 다르게 하고 있나요?
자세한 내용은.
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
목록 자체에는 이상한 점이 없습니다. 숨겨진 문자 없이 다른 목록으로 재현할 수 있습니다.
$ 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
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>
이는 Ubuntu, bash, 버전 4.4.20(1) 릴리스를 실행하는 시스템에서 발생합니다. 한번 사용해 보고 싶다면 를
efetch
사용하여 도구를 설치할 수 있습니다.sudo apt install ncbi-entrez-direct
루프에서 다른 언어를 사용하면 예상대로 작동합니다. 예를 들면 다음과 같습니다
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를 참조하세요.