bash:echo:書き込みエラー:システムコールが中断されました


9

8桁のすべての数字(00000000から99999999)を含む並べ替えられたリストを生成したいと思います。シェルに次のように入力しました。

f() {
 while IFS="" read -r line; do
   for i in {0..9}; do 
       echo "$line$i";
   done;
 done
}

echo | f | f | f | f | f | f | f | f | tee result.txt | wc -l

応答は

bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890

これら3つのエラーと不正な形式のresult.txtが表示されるのはなぜですか?

私が使う

GNU bash、バージョン4.4.12(1)-release(x86_64-pc-linux-gnu)

Debian GNU / Linux 9.6(ストレッチ)

Linuxカーネル:4.19.0#2 SMP Thu Nov 1 15:31:34 EET 2018 x86_64 GNU / Linux


2
仕方がないのですが、この方法で感じるのは、ほど効率的ではありませんseq -w 0 99999999
クサラナンダ

1
次に、質問は不完全/正しくない/不適切に書かれたものか何かです。スクリプトが(で完了した場合})正しく機能するためです。@ GAD3R
アイザック

1
注:これらのエラーはほとんどオンデマンドでトリガーできます。konsoleウィンドウのサイズを変更すると、よく表示されます。私の場合、そのようなサイズ変更はほぼ十分ですが、必ずしも必要ではありません。
カミルMaciorowski

を削除して| tee result.txtもエラーが発生します。
ctrl-alt-delor 2018

別のメモ:ビルトインの/bin/echo代わりに外部実行可能ファイル(私の場合)を使用echoすると、この問題の影響を受けなくなります(または、少なくとも発生しにくくなります)。
カミルMaciorowski

回答:


6

write error: Interrupted system callスクリプトの実行中にコンソールウィンドウのサイズが変更されると、特定のエラーが生成されます。

行うこと:

 trap '' SIGWINCH

それを避けます。

注意してください

 seq 99999999 >result.txt; wc -l <result.txt

両方が速くなり、SIGWINCH問題が回避されます。


5
それで何が起こっているのですか?なぜこれまでにこれを見たことがないのですか?、なぜ書き込みエラーなのですか?
ctrl-alt-delor 2018

4

これは実際にはのバグ[1]でありbash、だけでなくSIGWINCH、トラップが設定されたすべての信号でも発生します。

{ pid=$BASHPID; trap : USR1; (sleep 1; kill -USR1 $pid) &
         printf %0100000d 1; } | sleep 3600
bash: printf: write error: Interrupted system call

それはので、起こるbash)は、aに失敗すると、そのシグナルハンドラを設定するSA_RESTART以外(SIGCHLDハンドラ)、またはb)ハンドルEINTRを呼び出すときwrite()printfし、echo組み込みコマンド。

EINTR(「中断されたシステムコール」)はエラー状態を示す方法ではありませんが、プログラマがブロック読み取り/書き込みなどをメインループ内の信号の処理と組み合わせることができるハックです。ユーザーに漏洩することはありません。

このバグは頻繁に表示されません。適切な条件を整えるのはかなりの偉業であるためです。これwrite()組み込みコマンド(外部コマンドではなく)で実行する必要があり、パイプバッファーをいっぱいにする必要があります(他のリーダー)。 endは非常に遅くなるか、パイプからの読み取りがまったく行われなくなりますが、まだ有効です)、スクリプトはトラップを使用するか、ターミナルウィンドウのサイズを変更する必要があります。

そして、さまざまな実装アーティファクトのため、これwrite()read()sやopen()s ではなく、中断されたsにのみ影響します(たとえばopen()、名前付きパイプ/ fifoのブロックなど)。

[1]この形式はすでに少し前に報告されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.