Linux Bash命令在循环内不工作

Linux Bash命令在循环内不工作,linux,bash,Linux,Bash,我有这段代码 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 man

我有这段代码

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
问题是,当放置在for循环中时,grep命令会出错。使用方法:grep[OPTION]。。。模式[文件]。。。 有关详细信息,请尝试“grep--help”


但是当放置在for循环之外时,我没有得到这样的错误。我的循环是否存在干扰grep的问题?

您使用grep时,选项的顺序不正确,
[f]
字符类是不必要的。来自曼·格雷普

grep [OPTIONS] PATTERN [FILE...]
因此,您应该将
正在运行的\u进程
命令更改为

RUNNING_PROCESS=`ps aux | grep -c ffmpeg`
另外,为什么要使用
[f]fmpeg
字符类
[f]
将只匹配/扩展到
f
,因此请删除它以防止grep将其解释为模式的一部分。此外,它作为通配符没有帮助,因为
fmpeg
将匹配任何
ffmpeg
将匹配的内容。

您正在使用的

RUNNING_PROCESS=`ps aux | grep [f]fmpeg -c`
统计当前运行的
ffmpeg
的进程实例

使用
[f]
使
grep[f]fmpeg
与它自己的命令行不匹配,这很好

但是有一个问题:
[f]
是不带引号的,因此shell可能会尝试解释它,具体取决于选项

引用它应该使该行起作用:

RUNNING_PROCESS=`ps aux | grep '[f]fmpeg' -c`
这还有另一个问题:它不仅匹配
ffmpeg-a foo-b条…
,而且还匹配
less ffmpeg manual.txt
vim notes on ffmpeg commands.txt

但是有一个更好的方法可以做到这一点——使用合适的工具来完成这项工作。
ps
是列出流程的权利,但对于匹配流程,
pgrep
更适合:

RUNNING_PROCESS=$(pgrep -c ffmpeg)
ffmpeg
的进程计数输入
正在运行的\u进程中,是否符合您的需要

以上内容适用于Linux中常见的包
procps
pgrep
。有些版本不支持使用
-c
进行计数,或者使用
-c
进行其他操作。如果不起作用,请使用:

RUNNING_PROCESS=$(pgrep ffmpeg | wc -l)
pgrep
自行处理不匹配的问题,因此不需要
[f]
解决方法。
我还替换了后面的引号“…”通过
$(…)
,如果需要嵌套它,它有一些优点


如果您不仅需要匹配命令名,而且还需要匹配命令行,请使用
pgrep-f

问题是您使用的
[和
]
是作为
grep`模式,但模式是无引号的。在BASH中尝试以下操作:

RUNNING_PROCESS=$(ps aux | grep '[f]fmpeg' -c)
或者,如果您有
pgrep
,则可以使用:

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

不知道为什么代码在循环中的行为会有任何不同,但你应该检查一下,因为你的脚本中有很多东西可以整理。只要
grep fmpeg
-它会发现
ffmpeg
要考虑将你所有的
$f
放在双引号内,这样你就可以处理文件名中有空格的文件,从而
“$f”
i正在获取pgrep:invalid选项--“c”用法:pgrep[-flvx][d DELIM][n |-o][P-PPIDLIST][g-PGRPLIST][s-SIDLIST][u-EUIDLIST][u-UIDLIST g-GIDLIST][t TERMLIST PATTERN][h。。。我在Ubuntu14.4上,
pgrep——procpsNG3.3.9的版本
pgrep。你使用的是某种BSD变体吗?是的,我使用的是亚马逊自己的linuxflavor@user3148070好的,添加了另一个选项。Solaris下还有一个
pgrep
,它具有
-c
,但用于其他内容。这给出了一个错误的计数,因为
grep
将在
ps
输出中匹配自身。他使用[f]fmpeg以避免grep在ps aux列表中找到自己。这还将计算在命令参数中包含
ffmpeg
的其他进程,例如
vim notes on ffmpeg commands.txt
。当然可以在
grep
中找到。回答的目的是修复OP在
grep
命令中出现的错误。这就是你否决投票的原因吗?是的,我看不出还有其他潜在的原因。我明白你的观点,解决这个问题不是问题的一部分;但是,答案中的命令仍然意味着它获得了运行
ffmpeg
进程的计数,而它没有。我在答案中写道答案试图避免
vim abc ffmpeg.txt
进程。我们不要把这两个不同的问题混为一谈。好吧,你几乎说服了我;)哦,看来在编辑之前我不能“取消注释”。