1

i have this piece of code

for f in ${CURRENT_IMAGE_FILES[@]}; 
do 
    echo "Checking if too many process are running"
    while :
    do
        RUNNING_PROCESS=`ps aux | grep [f]fmpeg -c`
        if [[ $RUNNING_PROCESS -gt 22 ]]
        then
            echo "Too many process running now, sleep for 1 second"
            sleep 1
        else
            echo "Total ffmpeg process running is less then 20, continue"
            echo "current process count is " $RUNNING_PROCESS
            break
        fi
    done
    convert $f -resize 1280x720 -gravity center $f
    composite -gravity center $f /var/bash/b.jpg $f
    ffmpeg -loop 1 -f image2 -i $f -c:v libx264 -pix_fmt yuvj420p -preset ultrafast -t 3 $DIR/$COUNT.mp4 &
    ((++COUNT))
done

The thing is that when place inside the for loop, grep command is getting an error. Something along the lines of Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more information.

But when place outside the for loop, i do not get such error. Is there something wrong with my loop that is interfering with grep?

3
  • 2
    Not sure why the code behaves any differently inside a loop but you should check out shellcheck.net as there are a lot of things that you can tidy up in your script. Commented Sep 17, 2014 at 7:06
  • Just grep fmpeg - it will find ffmpeg too Commented Sep 17, 2014 at 7:08
  • 1
    Consider putting all your $f inside double quotes so you can process files with spaces in their names, thus "$f" Commented Sep 17, 2014 at 7:16

3 Answers 3

1

You are using grep with the options in the wrong order and the [f] character class is unnecessary. From man grep

grep [OPTIONS] PATTERN [FILE...]

So you should change your RUNNING_PROCESS command to

RUNNING_PROCESS=`ps aux | grep -c ffmpeg`

Additionally, why are you using [f]fmpeg? The character class [f] will only match/expand to f, so get rid of it to prevent grep from interpreting it as part of the pattern. Further, it does not help as a wildcard as fmpeg will match anything ffmpeg will match.

Sign up to request clarification or add additional context in comments.

2 Comments

This gives a wrong count, because the grep will match itself in the ps output.
He uses [f]fmpeg to avoid grep finding himself on the ps aux list.
1

You are using

RUNNING_PROCESS=`ps aux | grep [f]fmpeg -c`

to count the process instances of ffmpeg currently running.

The [f] is used so that grep [f]fmpeg does not match it's own command line, that's good.

But there's a problem: The [f] is unquoted, so the shell may try to interpret it, depending on options.

Quoting it should make the line work:

RUNNING_PROCESS=`ps aux | grep '[f]fmpeg' -c`

There is another problem in this: it matches not only ffmpeg -a foo -b bar ..., but also less ffmpeg-manual.txt or vim notes-on-ffmpeg-commands.txt.

But there is a better way to do that - using the right tool for the job. ps is the right to list processes, but for matching processes, pgrep is better suited:

RUNNING_PROCESS=$(pgrep -c ffmpeg)

does the what you need, getting the count of processes of ffmpeg into RUNNING_PROCESS.

The above works for pgrep of the package procps, common in Linux. There are versions that do not support -c for count, or use -c for something else. If it does not work, use:

RUNNING_PROCESS=$(pgrep ffmpeg | wc -l)

pgrep takes care of not matching itself on its own, so there is no need for the [f] workaround.
I also replaced the back quotes ` ... ` by $( ... ), which has some advantages if you need to nest it.

If you do need to match not only command name, but command line too, use pgrep -f.

4 Comments

i'm getting pgrep: invalid option -- 'c' Usage: pgrep [-flvx] [-d DELIM] [-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST] [-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] [PATTERN]
Oh... I'm on Ubuntu 14.4, pgrep --version says pgrep from procps-ng 3.3.9. Are you on some BSD variant?
Yea , i am using Amazon own linux flavor
@user3148070 Ok, added the alternative. There is also a pgrep under Solaris that has -c, but for something else.
0

Problem is that you are using [ and]asgrep` pattern but pattern is unquoted. Try this in BASH:

RUNNING_PROCESS=$(ps aux | grep '[f]fmpeg' -c)

Alternatively if you have pgrep then you can use:

RUNNING_PROCESS=$(pgrep -f 'ffmpeg' | wc -l)

5 Comments

This would both also count other processes that have ffmpeg in a command argument, like vim notes-on-ffmpeg-commands.txt.
Yes of course that will be found in grep. Intent of answer was to fix the error OP was getting in grep command. Is that the reason for you to downvote?
It is, an I see no other potential reason. I see your point that it is not part of the question to fix that; But still, the command in the answer implies that it gets the count of running ffmpeg processes, while it does not.
No where I wrote in my answer that answer is trying to avoid vim abc-ffmpeg.txt processes. Let's not mix the 2 different issues here.
Ok, you almost convinced me ;) Oh, looks like I can not "unvote" until an edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.