0

这是我正在做的一个例子;这个 shell 片段运行一个 django web 服务器以及一个运行 webpack 的 npm 进程(监视文件更改和重新加载/重新编译等)。为了方便起见,我将它们组合成一个可以通过 npm 运行的命令,但我觉得我忘记了一些看起来比这更好的简单命令:

p=0; q=0; endit() { kill -9 $p; kill -9 $q; }; trap endit INT; records/manage.py runserver & p=$!; npm run watch & wait; q=$!; wait $p; wait $q; endit

帮助我和我老化的记忆!:)

4

2 回答 2

1

您可以通过使用终止所有正在运行的作业来摆脱pq变量。kill $(jobs -p)同样,wait没有参数将等到所有正在运行的作业完成。

关于您的代码的另外 2 个注释:

  • 您应该调用exit陷阱命令,否则脚本即使在收到后仍将继续SIGINT(导致最终wait调用失败,因为进程已经终止)。
  • 您不应endit()在脚本末尾调用陷阱命令 ( ),因为此时进程已因wait调用而完成。

我用演示sleep命令测试了代码:

trap 'kill $(jobs -p); exit' INT;
sleep 5 &
sleep 5 &
wait
于 2021-01-09T19:18:17.063 回答
0

这是我想的最简单的版本,我猜。在我的情况下,用法是:

runon.py 'records/manage.py runserver' 'npm run watch'

这行得通,只是感觉还有更简单的东西。

#!/usr/bin/env python3

import sys
import argparse
import subprocess
import time
import shlex

parser = argparse.ArgumentParser(
    description='Manage multiple running commands.')
parser.add_argument('cmds', metavar="'cmdline -opts'", type=str, nargs='+',
                    help='a shell command to run')
args = parser.parse_args()

calls = {}.fromkeys(args.cmds)
for cmd in calls.keys():
    calls[cmd] = subprocess.Popen(shlex.split(cmd), text=True)
    print'start(%d): %s' % (calls[cmd].pid, cmd)

while calls:
    finished = []
    for name, call in calls.items():
        ret = call.poll()
        if ret is not None:
            print('return(%d): %s' % (ret, name))
            finished.append(name)
    for n in finished:
        calls.pop(n)
    time.sleep(0.5)
于 2021-01-10T14:12:54.353 回答