ImageMagick()で出力をリダイレクトし、入力を取得するために名前付きパイプ(たとえば、生成を使用)とファイル記述子を使用するのにmkfifo
問題があります。convert
デフォルトでは、次のbash
コード(私が試しているコードとは簡単)を使用すると、スクリプトが中断され、画像は表示されません。
#!/bin/bash
mkfifo myPipe # Create a named pipe
exec 3<>myPipe # I/O file descriptor using the pipe
convert rose: -resize 640x480\! png:fd:3 # Write the image to the pipe
convert png:fd:3 win: # To read from the pipe using the file descriptor
exec 3>&- # Close the file descriptor
rm myPipe # Close and remove the pipe
ちょっと調べてみたこここの段落(Jonathan Lefflerの答えから抜粋):
FIFO が読み取り用に開かれると、通常は呼び出しプロセスがブロックされます。プロセスが書き込み用に FIFO を開くと、リーダーはブロック解除されます。作成者がFIFOを閉じると、読み取りプロセスはEOF(読み取り可能なバイト数)を取得し、FIFOを閉じて再度開く以外は何もしません。
これを防ぐために、次のガイドライン(回答から取得したコード)を含むMark Edgarのソリューションを試しました。
# Create pipe and start reader.
mkfifo pipe
cat pipe &
# Open pipe for writing.
exec 3>pipe
echo one >&3
echo two >&3
# Close pipe.
exec 3>&-
残念ながら、パイプから読み取ってファイル記述子を使用して(たとえばをfd:X
使用してconvert
)書き込む必要があります。停止の問題なくこれを達成するにはどうすればよいですか?
答え1
問題はそうです。
exec 3<>myPipe
デッドロックを防ぐには、FIFOのR端とW端を同時に開きます。
convert rose: -resize 640x480\! png:fd:3
次のコマンドが実行される前に完了する必要がある汎用/前景コマンド。潜在的に大量のデータを FIFO に書き込んで完了しませんが、FIFO バッファがいっぱいになるとブロックされ、スクリプトデッドロックが発生します。
これが発生しないようにするには、次のプロセスがその間にFIFOを空にしてFIFOがいっぱいになるのを防ぐために、このコマンドをバックグラウンドに配置する必要があります。
コメントで述べたように、この場合、名前付きパイプの代わりに通常のパイプを使用することをお勧めします。
convert rose: -resize 640x480\! png:fd:1 |
convert png:fd:0 win:
コード行が長すぎるのが気になる場合は、読みやすくするために行を連続して仕上げて行\
に||
&&
|