简体   繁体   English

从bash并行运行多个脚本,而无需将输出打印到控制台

[英]Running multiple scripts from bash on parallel without printing output to console

Let assume I have multiple files paths for run from terminal, I want them to be run on parallel in the background without printing their output to the console screen. 假设我有多个文件路径可从终端运行,我希望它们在后台并行运行而不将其输出打印到控制台屏幕。 (Their output should be saved to some other log path which is defined in the python file itself). (它们的输出应保存到python文件本身定义的其他日志路径中)。

The paths are in this format: 路径采用以下格式:

/home/Dan/workers/1/run.py  
/home/Dan/workers/2/run.py etc.  

When I try to do something like running one worker in background it seems to work: 当我尝试执行一些操作,例如在后台运行一个工作程序时,似乎可以正常工作:
In example: cd /home/Dan/workers/1/ and python run.py > /dev/null 2>&1 & 例如: cd /home/Dan/workers/1/python run.py > /dev/null 2>&1 &

And ps -ef |grep python , indeed show the script running on background without printing to console, but printing to its predefined log path. ps -ef |grep python确实显示了在后台运行的脚本,而无需打印到控制台,而是打印到其预定义的日志路径。

However, when I try to launch them all via bash script, I've no python scripts run after the following code: 但是,当我尝试通过bash脚本启动它们时,在以下代码之后我没有运行python脚本:

#!/bin/bash
for path in /home/Dan/workers/*
do
 if [-f path/run.py ]
 then 
  python run.py > /dev/null 2>&1 &
 fi
done

Any idea what is the difference? 知道有什么区别吗? In bash script I try to launch many scripts one after another just like I did for only one script. 在bash脚本中,我尝试一个接一个地启动许多脚本,就像我对一个脚本所做的那样。

#!/bin/bash
for path in /home/Dan/workers/*
do         # VV    V-added ${}
    if [ -f "${path}/run.py" ]
    then 
        python "${path}/run.py" > /dev/null 2>&1 &
        # or (cd $path; python run.py > /dev/null 2>&1 &) like Terje said
    fi
done
wait

Use ${path} instead of just path . 使用${path}而不是path path is the name of the variable, but what you want when you are testing the file is the value that is stored in path . path是变量的名称,但是测试文件时所需的是存储在path To get that, prefix with $ . 为此,请在$前面加上前缀。 Note that $path will also work in most situations, but if you use ${path} you will be more clear about exactly which variable you mean. 请注意, $path在大多数情况下也可以使用,但是如果使用${path} ,则可以更清楚地知道要使用的变量。 Especially when learning bash, I recommend sticking with the ${...} form. 特别是在学习bash时,我建议坚持使用${...}表单。

Edit : Put the whole name in double-quotes in case ${path} contains any spaces. 编辑 :将全名放在双引号中,以防${path}包含任何空格。

#!/bin/bash

There is nothing bash-specific about this script; 此脚本没有特定于bash的内容; write #! /bin/sh #! /bin/sh #! /bin/sh instead. #! /bin/sh代替。 (Don't write bash-specific scripts, ever; if a bash-specific feature appears to be the easiest way to solve a problem, that is your cue to rewrite the entire thing in a better programming language instead.) (永远不要编写特定于bash的脚本;如果特定于bash的功能似乎是解决问题的最简单方法,那么您可以使用一种更好的编程语言来重写整个内容。)

for path in /home/Dan/workers/*
do

This bit is correct. 这个位是正确的。

  if [-f path/run.py ]

... but this is wrong. ...但这是错误的。 Shell variables are not like variables in Python. Shell变量不同于Python中的变量。 To use (the jargon term is "expand") a shell variable you have to put a $ in front of it. 使用一个shell变量(术语是“ expand”),必须在其前面加上一个$ Also, you need to put double quotation marks around the entire "word" containing the shell variable to be expanded, or "word splitting" will happen, which you don't want. 另外,您需要在包含要扩展的shell变量的整个“单词”两边加上双引号,否则会发生“单词拆分”,这是您不希望的。 (There are cases where you want word splitting, and then you leave the double quotes out, but only do that when you know you want word splitting.) Also also, there needs to be a space between [ and -f . (在某些情况下,您希望拆分单词,然后省略双引号,但只有在您知道要拆分单词时才这样做。)而且, [-f之间必须有一个空格。 Putting it all together, this line should read 放在一起,这行应该读

  if [ -f "$path/run.py" ]

.

  then 
    python run.py > /dev/null 2>&1 &
  fi

The run.py on this line should also read "$path/run.py" . 此行上的run.py也应显示为"$path/run.py" It is possible, depending on what each python script does, that you instead want the entire line to read 根据每个python脚本的作用,您可能希望整个行都读取

    ( cd "$path" && exec python run.py > /dev/null 2>&1 ) &

I can't say for sure without knowing what the scripts do. 我不能肯定地说不知道脚本会做什么。

done

There should probably be another line after this reading just 在阅读之后可能应该还有另一行

wait

so that the outer script does not terminate until all the workers are done. 这样外部脚本就不会终止,直到所有工作程序都完成为止。

One important difference is that your bash script does not cd into the subdirectories before calling run.py 一个重要的区别是您的bash脚本在调用run.py之前不会进入子目录
The second last line should be 最后第二行应该是

python ${path}/run.py > /dev/null 2>&1 &

or 要么

(cd $path; python run.py > /dev/null 2>&1 &)

What I would suggest is, not to invoke via loop. 我建议的是不要通过循环调用。 Your path suggests that you will be having multiple scripts. 您的路径表明您将拥有多个脚本。 Actually the loop statement which you have included invokes each python script sequentially. 实际上,您所包含的loop语句会依次调用每个python脚本。 It will run second one only when first one is over. 仅当第一个结束时,它才会运行第二个。

Better add 更好地添加

#!/bin/python on the top in your python scripts (or whichever path your python is installed) and then run #!/bin/python在您的python脚本的顶部(或安装python的路径)中,然后运行

/home/Dan/workers/1/run.py && /home/Dan/workers/2/run.py > /dev/null 2>&1 &

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM