如何在 运行 时更改一系列 bash 命令?
how to change a sequence of bash commands while running?
假设我想按顺序 运行 两个 python 脚本。我目前的解决方案是编写一个 bash run.sh 脚本,其中可以包含如下内容:
python foo.py
python bar.py
现在假设在终端中执行 ./run.sh 命令后 foo.py 为 运行ning(bar.py 尚未启动),我想运行baz.py(在执行./run.sh命令后创建的)而不是bar.py。 run.sh 脚本现在看起来像这样:
python foo.py
python baz.py
那么我的问题是:这可能吗?澄清一下:有没有办法即时修改命令行序列?此序列不必包含在 bash 文件中,并且可能涉及一些我不知道的 workflow/pipeline 管理程序。
主要目标是拥有一个我可以即时更改的动态进程列表。
我建议为此使用 python 解决方案。使用线程,您可以 运行 “并行”处理事物。我制作了一个 run.py
文件,然后可以通过 bash 成为 运行。这只是原则。您可以将 'run.py' 文件中的输入更改为适合您的目的。
第一个线程启动 run1()
,然后通过导入启动 test1.py
。当发生这种情况时,第二个线程“并行”开始 run2
并要求您提供输入。如果输入是 2 test2.py
启动,如果输入是 3 test3.py
启动 运行 与 test1.py
“并行”,如果尚未完成。
# test1.py
import time
print("This is test1.py running")
time.sleep(10)
print("This is test1.py finishing")
# test2.py
import time
print("This is test2.py running")
time.sleep(10)
print("This is test2.py finishing")
# test3.py
import time
print("This is test3.py running")
time.sleep(10)
print("This is test3.py finishing")
# run.py
import threading
def run1():
import test1
def run2():
i = int(input("2 or 3: "))
if i == 2:
import test2
elif i == 3:
import test3
else:
print("jumped over 2 and 3")
t1 = threading.Thread(target=run1)
t2 = threading.Thread(target=run2)
t1.start()
t2.start()
t1.join()
t2.join()
让您的 Python 脚本 foo.py
将您想要的脚本的名称写入文件 ./.script
,如下所示:
# imports
with open('./.script.py', 'w') as f:
f.write('python bar.py')
# do stuff
if condition:
with open('./.script.py', 'w'):
f.write('python baz.py')
那么你的脚本可以看起来像
#!/bin/bash
python foo.py
`cat .script`
无需即时修改。
保持简单。
#! /bin/bash
python3 foo.py
second=$(< second)
python3 "${second:-bar.py}"
如果您将 baz.py
写入 second
文件(即使您从 foo.py
写入它),那么 run.sh
将执行它而不是 bar.py
使用数据库中的动态任务
# create sqlite db with your tasks
$ sqlite3 mydb.sql
sqlite> create table tasks (id integer primary key, name text);
sqlite> insert into tasks values (1,"foo.py");
sqlite> insert into tasks values (2,"bar.py");
sqlite> select * from tasks;
1|foo.py
2|bar.py
run.sh
#!/bin/bash
MYDB="./mydb.sql"
execTask(){
local id=
task=$(sqlite3 $MYDB "select name from tasks where id = ")
[ -z "$task" ] && { echo "no task found for id $id" ; return 1; }
echo "exec task $task"
python3 $task
}
execTask 1
execTask 2
输出:
$ bash run.sh
exec task foo.py
exec task baz.py
从控制台或其他脚本更新任务table
$ sqlite3 mydb.sql "update tasks set name = 'baz.py' where id = 2"
我使用 slurm 解决了我自己的问题。我发现我的问题与此类似 post: What is the simplest queue job manager for linux?
正如我在问题结尾所说的那样,我需要一个作业管理器工具(因此比 over-simplified 示例中介绍的简单脚本的执行更通用)。我知道 slurm,但我想看看是否有人知道可以在个人计算机上使用的更简单的东西(涉及 bash 或其他软件,而不是经历我在安装 slurm 时遇到的所有困难)。
如果有人想在他们的个人笔记本电脑上使用 slurm(我用 Ubuntu 20.04 测试过),我建议关注以下博客 posts:
- https://signac.io/development/2020/06/26/local-SLURM-environment.html
- https://blog.llandsmeer.com/tech/2020/03/02/slurm-single-instance.html
最难的部分是slurm.conf创作(https://slurm.schedmd.com/configurator.html)。为了对我自己的安装过程进行反馈,我建议:
- 以 root 用户身份进行安装,
- 将 SlurmUser 设置为 root
- 将 SlurmctldHost 和 NodeName 设置为您计算机的名称
- 让其他参数默认
感谢@Zorgoth、@Diego Torres Milano、@ufopilot 和@perperam 提出的建议。
假设我想按顺序 运行 两个 python 脚本。我目前的解决方案是编写一个 bash run.sh 脚本,其中可以包含如下内容:
python foo.py
python bar.py
现在假设在终端中执行 ./run.sh 命令后 foo.py 为 运行ning(bar.py 尚未启动),我想运行baz.py(在执行./run.sh命令后创建的)而不是bar.py。 run.sh 脚本现在看起来像这样:
python foo.py
python baz.py
那么我的问题是:这可能吗?澄清一下:有没有办法即时修改命令行序列?此序列不必包含在 bash 文件中,并且可能涉及一些我不知道的 workflow/pipeline 管理程序。 主要目标是拥有一个我可以即时更改的动态进程列表。
我建议为此使用 python 解决方案。使用线程,您可以 运行 “并行”处理事物。我制作了一个 run.py
文件,然后可以通过 bash 成为 运行。这只是原则。您可以将 'run.py' 文件中的输入更改为适合您的目的。
第一个线程启动 run1()
,然后通过导入启动 test1.py
。当发生这种情况时,第二个线程“并行”开始 run2
并要求您提供输入。如果输入是 2 test2.py
启动,如果输入是 3 test3.py
启动 运行 与 test1.py
“并行”,如果尚未完成。
# test1.py
import time
print("This is test1.py running")
time.sleep(10)
print("This is test1.py finishing")
# test2.py
import time
print("This is test2.py running")
time.sleep(10)
print("This is test2.py finishing")
# test3.py
import time
print("This is test3.py running")
time.sleep(10)
print("This is test3.py finishing")
# run.py
import threading
def run1():
import test1
def run2():
i = int(input("2 or 3: "))
if i == 2:
import test2
elif i == 3:
import test3
else:
print("jumped over 2 and 3")
t1 = threading.Thread(target=run1)
t2 = threading.Thread(target=run2)
t1.start()
t2.start()
t1.join()
t2.join()
让您的 Python 脚本 foo.py
将您想要的脚本的名称写入文件 ./.script
,如下所示:
# imports
with open('./.script.py', 'w') as f:
f.write('python bar.py')
# do stuff
if condition:
with open('./.script.py', 'w'):
f.write('python baz.py')
那么你的脚本可以看起来像
#!/bin/bash
python foo.py
`cat .script`
无需即时修改。
保持简单。
#! /bin/bash
python3 foo.py
second=$(< second)
python3 "${second:-bar.py}"
如果您将 baz.py
写入 second
文件(即使您从 foo.py
写入它),那么 run.sh
将执行它而不是 bar.py
使用数据库中的动态任务
# create sqlite db with your tasks
$ sqlite3 mydb.sql
sqlite> create table tasks (id integer primary key, name text);
sqlite> insert into tasks values (1,"foo.py");
sqlite> insert into tasks values (2,"bar.py");
sqlite> select * from tasks;
1|foo.py
2|bar.py
run.sh
#!/bin/bash
MYDB="./mydb.sql"
execTask(){
local id=
task=$(sqlite3 $MYDB "select name from tasks where id = ")
[ -z "$task" ] && { echo "no task found for id $id" ; return 1; }
echo "exec task $task"
python3 $task
}
execTask 1
execTask 2
输出:
$ bash run.sh
exec task foo.py
exec task baz.py
从控制台或其他脚本更新任务table
$ sqlite3 mydb.sql "update tasks set name = 'baz.py' where id = 2"
我使用 slurm 解决了我自己的问题。我发现我的问题与此类似 post: What is the simplest queue job manager for linux?
正如我在问题结尾所说的那样,我需要一个作业管理器工具(因此比 over-simplified 示例中介绍的简单脚本的执行更通用)。我知道 slurm,但我想看看是否有人知道可以在个人计算机上使用的更简单的东西(涉及 bash 或其他软件,而不是经历我在安装 slurm 时遇到的所有困难)。
如果有人想在他们的个人笔记本电脑上使用 slurm(我用 Ubuntu 20.04 测试过),我建议关注以下博客 posts:
- https://signac.io/development/2020/06/26/local-SLURM-environment.html
- https://blog.llandsmeer.com/tech/2020/03/02/slurm-single-instance.html
最难的部分是slurm.conf创作(https://slurm.schedmd.com/configurator.html)。为了对我自己的安装过程进行反馈,我建议:
- 以 root 用户身份进行安装,
- 将 SlurmUser 设置为 root
- 将 SlurmctldHost 和 NodeName 设置为您计算机的名称
- 让其他参数默认
感谢@Zorgoth、@Diego Torres Milano、@ufopilot 和@perperam 提出的建议。