我正在尝试编写一个.sh文件,同时运行许多程序
我试过了
prog1
prog2
但是它会运行prog1,然后等待prog1结束,然后启动prog2……
那么如何并行运行呢?
我正在尝试编写一个.sh文件,同时运行许多程序
我试过了
prog1
prog2
但是它会运行prog1,然后等待prog1结束,然后启动prog2……
那么如何并行运行呢?
当前回答
如果您有一个GUI终端,您可以为希望并行运行的每个进程生成一个新的选项卡终端实例。
这样做的好处是,每个程序都在自己的选项卡中运行,它可以独立于其他运行的程序进行交互和管理。
例如,在Ubuntu 20.04上:
gnome-terminal --tab -- bash -c 'prog1'
gnome-terminal --tab -- bash -c 'prog2'
要按顺序运行某些程序或其他命令,可以添加;
gnome-terminal --tab -- bash -c 'prog1_1; prog1_2'
gnome-terminal --tab -- bash -c 'prog2'
我发现对于某些程序,终端在启动之前就关闭了。对于这些程序,我将终端命令与;等待或;睡眠1
gnome-terminal --tab -- bash -c 'prog1; wait'
对于Mac OS,你必须为你正在使用的终端找到一个等效的命令——我没有在Mac OS上测试,因为我没有Mac。
其他回答
我最近遇到了类似的情况,我需要同时运行多个程序,将它们的输出重定向到独立的日志文件中,然后等待它们完成,最后我得到了这样的结果:
#!/bin/bash
# Add the full path processes to run to the array
PROCESSES_TO_RUN=("/home/joao/Code/test/prog_1/prog1" \
"/home/joao/Code/test/prog_2/prog2")
# You can keep adding processes to the array...
for i in ${PROCESSES_TO_RUN[@]}; do
${i%/*}/./${i##*/} > ${i}.log 2>&1 &
# ${i%/*} -> Get folder name until the /
# ${i##*/} -> Get the filename after the /
done
# Wait for the processes to finish
wait
来源:http://joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
你的脚本应该是这样的:
prog1 &
prog2 &
.
.
progn &
wait
progn+1 &
progn+2 &
.
.
假设你的系统一次可以处理n个任务。使用wait一次只运行n个作业。
这里有很多有趣的答案,但我从这个答案中获得了灵感,并将一个简单的脚本组合在一起,并行运行多个进程,并在完成后处理结果。你可以在以下要点中找到它:
#!/usr/bin/env bash
# inspired by https://stackoverflow.com/a/29535256/2860309
pids=""
failures=0
function my_process() {
seconds_to_sleep=$1
exit_code=$2
sleep "$seconds_to_sleep"
return "$exit_code"
}
(my_process 1 0) &
pid=$!
pids+=" ${pid}"
echo "${pid}: 1 second to success"
(my_process 1 1) &
pid=$!
pids+=" ${pid}"
echo "${pid}: 1 second to failure"
(my_process 2 0) &
pid=$!
pids+=" ${pid}"
echo "${pid}: 2 seconds to success"
(my_process 2 1) &
pid=$!
pids+=" ${pid}"
echo "${pid}: 2 seconds to failure"
echo "..."
for pid in $pids; do
if wait "$pid"; then
echo "Process $pid succeeded"
else
echo "Process $pid failed"
failures=$((failures+1))
fi
done
echo
echo "${failures} failures detected"
结果是:
86400: 1 second to success
86401: 1 second to failure
86402: 2 seconds to success
86404: 2 seconds to failure
...
Process 86400 succeeded
Process 86401 failed
Process 86402 succeeded
Process 86404 failed
2 failures detected
#!/bin/bash
prog1 & 2> .errorprog1.log; prog2 & 2> .errorprog2.log
将错误重定向到单独的日志。
如果你是:
在Mac上使用iTerm 想要启动各种长期打开的进程,直到按Ctrl+C 希望能够轻松地看到每个进程的输出 希望能够轻松地使用Ctrl+C停止特定进程
如果你的用例更多的是应用监控/管理,一种选择是编写终端本身的脚本。
例如,我最近做了以下事情。当然,它是特定于Mac的,特定于iTerm的,并且依赖于已弃用的Apple Script API (iTerm有一个更新的Python选项)。它没有赢得任何优雅奖,但完成了任务。
#!/bin/sh
root_path="~/root-path"
auth_api_script="$root_path/auth-path/auth-script.sh"
admin_api_proj="$root_path/admin-path/admin.csproj"
agent_proj="$root_path/agent-path/agent.csproj"
dashboard_path="$root_path/dashboard-web"
osascript <<THEEND
tell application "iTerm"
set newWindow to (create window with default profile)
tell current session of newWindow
set name to "Auth API"
write text "pushd $root_path && $auth_api_script"
end tell
tell newWindow
set newTab to (create tab with default profile)
tell current session of newTab
set name to "Admin API"
write text "dotnet run --debug -p $admin_api_proj"
end tell
end tell
tell newWindow
set newTab to (create tab with default profile)
tell current session of newTab
set name to "Agent"
write text "dotnet run --debug -p $agent_proj"
end tell
end tell
tell newWindow
set newTab to (create tab with default profile)
tell current session of newTab
set name to "Dashboard"
write text "pushd $dashboard_path; ng serve -o"
end tell
end tell
end tell
THEEND