4

I have the following shell script and it is missing some initial characters (it misses initial couple of characters, so far in my observation) from each line except the first line.

And this happens only when I use the ffmpeg command. Otherwise, it is fine. But this command does the actual task in this script.

Why is it so and what is the fix?

#!/bin/bash

while read line; do
    printf "%s\n" "$line" 
    ifile=$line
    printf "%s\n" "$ifile" 
    ofile=abc_$line
    printf "%s\n" "$ofile" 

    ############### Problem is the following command: ##########
    ffmpeg -y -i $ifile -c:v libx264rgb -b:v 512k -bf 0 -pix_fmt rgb24  -r 25 -strict -2 $ofile
    ##########rest is fine##########

    echo $ifile
done < file_list
tod
  • 1,539
  • 4
  • 17
  • 43
  • 2
    The [incorrect quoting](/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) may be obscuring things. Does your input file have DOS carriage returns? (Try `cat -v`; if you see `^M` at the end of every line, you need `dos2unix`, or better yet stop using a Windows editor on your files.) – tripleee Apr 15 '19 at 04:19
  • 1
    @tripleee: I suspected the problem to be with not closing stdin, but then OP would have seen a different problem then – Inian Apr 15 '19 at 04:21

1 Answers1

9

This is pretty well explained in this post I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!. When reading a file line by line, if a command inside the loop also reads stdin, it can exhaust the input file. In your case ffmpeg also reads from stdin.

The most common symptom of this is a while read loop only running once, even though the input contains many lines. This is because the rest of the lines are swallowed by the offending command. The most common fix for the problem is to close the stdin of the ffmpeg by doing < /dev/null

ffmpeg -y -i "$ifile" -c:v libx264rgb -b:v 512k -bf 0 -pix_fmt rgb24  -r 25 -strict -2 "$ofile" < /dev/null

or use another file descriptor other than standard input

 while read -r line <&3; do
     ifile="$line"
     ofile="abc_${line}"
     ffmpeg -y -i "$ifile" -c:v libx264rgb -b:v 512k -bf 0 -pix_fmt rgb24  -r 25 -strict -2 "$ofile"
 done 3<file

Or your problem could altogether be a case of the input file having DOS style line endings carried over from a DOS environment. You can check that out by running the file command on the input file (file file_list) which could show CRLF line terminators. In such case do a clean-up of the input file as dos2unix file_list and re-run your script.

Inian
  • 80,270
  • 14
  • 142
  • 161