假设我有多个文件路径用于从终端运行, 我希望它们在后台并行运行,而不将其输出打印到控制台屏幕。 (它们的输出应该保存到python文件本身定义的其他日志路径中。)
路径采用以下格式:
/home/Dan/workers/1/run.py
/home/Dan/workers/2/run.py etc.
当我尝试做一些事情,比如在后台运行一名工人时,似乎有效:
例如:cd /home/Dan/workers/1/
和python run.py > /dev/null 2>&1 &
而ps -ef |grep python
确实显示脚本在后台运行而不打印到控制台,而是打印到其预定义的日志路径。
但是,当我尝试通过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
知道有什么区别吗? 在bash脚本中,我尝试一个接一个地启动许多脚本,就像我只为一个脚本一样。
答案 0 :(得分:3)
#!/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
使用${path}
代替path
。 path
是变量的名称,但在测试文件时您需要的是存储在path
中的值。为此,请使用$
作为前缀。请注意,$path
也适用于大多数情况,但如果您使用${path}
,您将更清楚地了解您所指的变量。特别是在学习bash时,我建议坚持使用${...}
表格。
修改:如果${path}
包含任何空格,请将整个名称放在双引号中。
答案 1 :(得分:2)
#!/bin/bash
这个剧本没有任何特定于bash的内容;写一下#! /bin/sh
。 (永远不要编写特定于bash的脚本;如果特定于bash的特性似乎是解决问题的最简单方法,那就是用更好的编程语言重写整个事物的提示。)
for path in /home/Dan/workers/*
do
这一位是正确的。
if [-f path/run.py ]
......但这是错误的。 Shell变量与Python中的变量不同。要使用(行话术语是"展开")一个shell变量,你必须在它前面放置一个$
。此外,你需要在整个"字#&34;周围加上双引号。包含要展开的shell变量,或者"单词拆分"会发生,你不想要的。 (有些情况下你想要分词,然后你把双引号留下来,但只有当你知道你想要分词时才这样做。)另外,那里也是需要是[
和-f
之间的空格。总而言之,这一行应该是
if [ -f "$path/run.py" ]
then
python run.py > /dev/null 2>&1 &
fi
此行中的run.py
也应该为"$path/run.py"
。根据每个python脚本的作用,您可能希望整行读取
( cd "$path" && exec python run.py > /dev/null 2>&1 ) &
在不知道脚本的用途的情况下,我无法肯定地说。
done
这次阅读后可能还有另一行
wait
这样在完成所有工作之前外部脚本不会终止。
答案 2 :(得分:1)
一个重要的区别是你的bash脚本在调用run.py之前不会进入子目录 第二行应该是
python ${path}/run.py > /dev/null 2>&1 &
或
(cd $path; python run.py > /dev/null 2>&1 &)
答案 3 :(得分:0)
我建议的是,不要通过循环调用。您的路径表明您将拥有多个脚本。实际上,你所包含的循环语句按顺序调用每个python脚本。只有在第一个结束时它才会运行第二个。
更好地添加
python脚本顶部的 #!/bin/python
(或者你的python安装的哪个路径)
然后运行
/home/Dan/workers/1/run.py && /home/Dan/workers/2/run.py > /dev/null 2>&1 &