'while read' ループでテキスト ファイルの行を処理した結果、Bash スクリプトで文字が失われます。FFmpeg 行が原因でしょうか?

'while read' ループでテキスト ファイルの行を処理した結果、Bash スクリプトで文字が失われます。FFmpeg 行が原因でしょうか?

私は「while read」を使用してテキスト ファイルをループしています。各行から 3 つの変数 (2 つのファイル名と 1 つの 10 進数) を読み取ります。入力ファイルでテストしたので、これは通常の設定 (ループ、行の読み取り、行のエコー、変数の抽出、その他はなし) で機能することがわかっています。

しかし、私のルーチンの核心である、ファイル名で表されるオーディオとビデオのストリームをマージするためにffmpegを呼び出すと、奇妙な結果が得られます。連続した「読み取り」操作により、行の先頭の文字が省略されます。ここ「while read」ループ内で「read」入力を呼び出すと問題が発生する可能性があり、ffmpeg 呼び出しが bash を混乱させるようなことを行っているのではないかと疑問に思いますが、これはありそうになく奇妙です。注: ffmpeg 呼び出しはよくわかりません。別の質問への回答から得たものです。

ご協力いただければ幸いです。

最初の「読み取り」は期待どおりに機能します (ffmpeg コマンドが完了します)。

LINE  1
vidsNeedingSound/448£generic@06_10_16-09_30_47.mp4 soundToAdd/448£generic@06_10_16-12_11_54.wav 6.988354
V: vidsNeedingSound/448£generic@06_10_16-09_30_47.mp4   A: soundToAdd/448£generic@06_10_16-12_11_54.wav   D: 6.988354

2 番目の「read」では、行の先頭から 36 文字が失われます (行の最初の項目を取得する変数 V によって表されるファイルがファイルを指していないため、ffmpeg コマンドは失敗します)。

LINE  2
6-09_30_47.mp4 soundToAdd/452£generic@06_10_16-12_11_54.wav 9.64663
V: 6-09_30_47.mp4   A: soundToAdd/452...

3 番目の「読み取り」は期待どおりに動作します (ffmpeg コマンドが完了します)。

LINE  3
vidsNeedingSound/452£left@06_10_16-09_30_47.mp4 soundToAdd/452£left@06_10_16-12_11_54.wav 9.862118
V: vidsNeedingSound/452£left@06_10_16-09_30_47.mp4   A: soundToAdd/452...

4 番目の「read」では、行の先頭から 37 文字 (最後の失敗より 1 文字多い) が失われます (ffmpeg コマンドは失敗します)。

LINE  4
09_30_47.mp4 soundToAdd/452£right@06_10_16-12_11_54.wav 9.431392
V: 09_30_47.mp4   A: soundToAdd/452....

これがパターンです。ffmpeg の呼び出しが成功していない場合、「read」は期待どおりに動作します。ffmpeg の呼び出しが成功するたびに、行の先頭から文字が省略されます。最初は 36 文字で、次に 37、38、39... となります。

決定的なのは、ffmpeg が「成功した」読み取り後に (別の問題により) 失敗した場合、次の「読み取り」が期待どおりに機能することです。

結論: ffmpeg 呼び出しが成功すると、ループの次の反復で読み取り失敗が発生します。

なぜこのようなことが起こるのでしょうか? また、どうすればこれを止めることができるのでしょうか?

私のコードは次のとおりです: ...

# Loop through lines in the merge file
IT_COUNT=1
while read MERGE_LINE           
    do         
    echo "LINE " $IT_COUNT
    ((IT_COUNT+=1))
    echo $MERGE_LINE   # testing use
    read VID_FILE AUD_FILE DURATION <<< "$MERGE_LINE" # Get the data from each line
    echo "V: $VID_FILE   A: $AUD_FILE   D: $DURATION"         # testing use
....
    # add audio to video
    ffmpeg -i $VID_FILE -i $AUD_FILE -filter_complex "aevalsrc=0:d=$AUD_SHIFT[s1];[s1][1:a]concat=n=2:v=0:a=1[aout]" -c:v copy -map 0:v -map [aout] $FILE_OUT -hide_banner

done <$MERGE_FILE  

ご覧いただきありがとうございます!

答え1

-nostdinのオプションを使用しますffmpegFFmpeg ドキュメント:

標準入力でのインタラクションを有効にします。標準入力が入力として使用されていない限り、デフォルトでオンになっています。インタラクションを明示的に無効にするには、 を指定する必要があります-nostdin

たとえば、ffmpeg がバックグラウンド プロセス グループにある場合、標準入力での対話を無効にすると便利です。ほぼ同じ結果が で達成できますffmpeg ... < /dev/nullが、シェルが必要です。

答え2

おそらく、ffmpeg が入力から読み取っているというのは正しいと思いますが、その理由は誰にもわかりません。したがって、そのコマンドを から読み取るようにリダイレクトするだけです。/dev/nullつまり、ffmpeg の行に を追加します</dev/null

関連情報