
whileループで特定のツール(NCBI Electronics Utility Suiteの)を使用しようとしているesearch
間、非常に奇妙な状況に直面しました。これは、1行に1つずつ文字列のリストである入力ファイルです。
$ 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
単一の結果を実行することでわかるように、これは3つではなく1つの結果です。しかし、私が使うと悪い習慣 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またはそのようなものに関連することはできません。このコマンドの終了状態は何があってもゼロです。
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
。
バラよりファイルを1行ずつ読み、sshまたはffmpegを実行すると、最初の行だけが処理されます。詳細については、Bash FAQをご覧ください。