如何使用bash shell多次运行命令?


153

是否可以运行命令(例如ps aux|grep someprocessn次?

就像是:

run -n 10  'ps aux|grep someprocess'

我想以交互方式使用它,请不要发布脚本。

更新:我要问的原因是,我确实在很多机器上工作,并且我不想将我所有的自适应脚本等导入每个框中,以便在每台机器上获得相同的功能。


Answers:


197

我认为不存在为此内置的命令或shell,因为它是Bourne shell for循环所设计的琐碎子集,因此自己实现这样的命令非常简单。

对于初学者,您可以使用虚拟for循环:

for i in `seq 10`; do command; done

或等效于按照JimB的建议,使用内置的Bash生成序列:

for i in {1..10}; do command; done

command每次执行都会迭代十次-它可以是管道,也可以是由;或分隔的一系列命令&&。您可以使用$i变量来知道您正在进行的迭代。

如果您将此单行代码视为脚本,并且由于某些未指定(但可能有效)的原因而令人不快,则可以将其作为命令实现,也许在您的.bashrc上这样(未经测试):

#function run
run() {
    number=$1
    shift
    for i in `seq $number`; do
      $@
    done
}

用法:

run 10 command

例:

run 5 echo 'Hello World!'

16
@mahatmanich,循环不是脚本。没有什么可以阻止您在交互式终端上使用...。
Zoredache

3
好吧,上面的单行代码是执行此操作的一种标准方法,并且非常简单。为什么对您不利?也许您问错了问题?您的脚本或要多次重复执行的操作的主要目标是什么?如果我们以不同的方式提出问题,也许会有更好的解决方案。
2011年

6
@mahatmanich- for 用于迭代的内置bash。
JimB 2011年

3
@Eduardo Ivanec-仅供参考,bash具有内置范围,例如seq{1..10}
JimB 2011年

1
似乎内置的括号序列不支持变量替换(请参阅stackoverflow.com/a/3737773/713554)。您所提供的功能可以很好地与.bashrcif {1..$number} 交换`seq $number`
2012年

29

ps aux | grep someprocess您似乎想在固定的时间内观看程序的更改。Eduardo给出了一个答案,可以准确回答您的问题,但是有另一种选择watch::

watch 'ps aux | grep someprocess'

请注意,我已将该命令放在单引号中,以避免shell将命令解释为“ run watch ps aux”,并将结果通过管道传递grep someprocess。执行上一个命令的另一种方法是:

watch ps aux \| grep someprocess

默认情况下,watch每两秒钟刷新一次,可以使用该-n选项进行更改。例如,如果要间隔1秒:

watch -n 1 'ps aux | grep someprocess'

21

纯娱乐

pgrep ssh ;!!;!!;!!;!!;!!;!!

有人可以解释一下吗?看起来很有趣。
Daniel Vartanov 2014年

4
; 只是命令分隔符。!! 重播bash中的最后一个命令。因此,运行“ pgrep ssh”,然后重播6次。
Piotr Kukielka 2014年

虽然这很有启发性,但并不直观。单线for似乎是最好的方法。无论如何,谢谢你的回答。
erm3nda 2015年

1
不在cmd ;!!一行上重复在当前行之前输入的命令吗?它必须是两个单独的history条目。
乔尔·普拉

更换;&&停在第一次失败。
user881300

16

与先前的回复类似,但是不需要for循环:

seq 10 | xargs -I -- echo "hello"

将seq的输出通过管道传递给xargs,不带参数或选项


2
这只会执行一个echo "hello" 1 2 3 4 5 6 7 8 9 10。您需要-n 1为每个输入(数字)对一个进程运行xargs,对于-P 10并行执行(10个并行进程)运行xargs 。最后以seq 10 | xargs -n 1 -P 10 echo
亚历山大·克里姆采切克

16

尝试这个:

yes ls | head -n5 | bash

这要求命令在子外壳中执行,这会稍微降低性能。YMMV。基本上,您可以通过“ yes”命令将字符串“ ls”重复N次;而“ head -n5”在5次重复中终止了循环。最终管道将命令发送到您选择的外壳。

顺便说一句,cshshell具有内置repeat命令。您可以使用它在bash子shell中执行命令!


5

POSIX方式

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01

x=10
while [ $x -gt 0 ]; do
    command
    x=$(($x-1))
done

当然可以将其制成一个衬套:

x=10; while [ $x -gt 0 ]; do command; x=$(($x-1)); done

并且似乎是最可移植的方式,因此不太可能使您安装程序。

以下内容不太便于移植:

  • 大括号扩展{1..10}:bash特定,如果参数很大,则会生成一条大行
  • seq:GNU
  • yes:GNU

如果您对可移植性感到厌倦,请考虑使用GNU parallel

sudo apt-get install parallel
seq 100 | parallel echo {}

它可以并行运行命令,并且有很多不错的选择。

另请参阅:https : //stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-defined-by-variables-in-bash


GNU Parallel的构建具有很高的可移植性。sh, zsh, ksh,并且bash在大多数平台上都得到很好的支持。csh, tcsh, fish有一些支持。使用parallel --embed您甚至可以构建一个可以轻松移动到未安装GNU Parallel的系统的脚本。
Ole Tange

2

上面 @ eduardo-ivanec run函数的鱼壳实现

function run
  set number $argv[1]
  for i in (seq $number)
    eval $argv[2..-1]
  end
end

0

那将是“监视”-应该成为几乎所有使用procps的unix系统的一部分

您可以看到fs的更改或系统中其他有趣的动作。例如,

watch "df -hP | grep /tmp" 

只需将命令作为参数即可(请参阅参考资料man watch


手表已经有了答案……请看下面...
mahatmanich

0

在macOS上,您可以使用repeat命令。

repeat 10 ps aux | grep someprocess
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.