简体   繁体   English

一起运行和监控多个 shell 命令的优雅方式是什么?

[英]What is the elegant way of running and monitoring multiple shell commands together?

Here is an example of what I am doing;这是我正在做的一个例子; this shell snippet runs a django web server as well as an npm process that runs webpack (both monitor for file changes and reload/recompile, etc). this shell snippet runs a django web server as well as an npm process that runs webpack (both monitor for file changes and reload/recompile, etc). I've combined them for convenience into one command I can run via npm, but I feel like I'm forgetting something simple that looks better than this:为了方便起见,我将它们组合成一个命令,我可以通过 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

Help me and my aging memory: :)帮助我和我老化的 memory ::)

You can get rid of p and q variables by using kill $(jobs -p) to terminate all running jobs.您可以通过使用kill $(jobs -p)终止所有正在运行的作业来摆脱pq变量。 Similarly, wait without arguments will wait until all running jobs finish.同样,没有 arguments 的wait将等到所有正在运行的作业完成。

2 more notes on your code:关于您的代码的另外 2 个注释:

  • You should call exit in trap command, otherwise your script will continue even after it receives SIGINT (causing the final wait call to fail, since processes have been already terminated).您应该在 trap 命令中调用exit ,否则您的脚本即使在收到SIGINT后仍将继续(导致最终wait调用失败,因为进程已经终止)。
  • You should not call trap command ( endit() ) in the end of the script, because at this point processes have already finished due to wait call.您不应该在脚本末尾调用陷阱命令( endit() ),因为此时进程由于wait调用而已经完成。

I tested the code with a demonstrative sleep command:我使用演示性sleep命令测试了代码:

trap 'kill $(jobs -p); exit' INT;
sleep 5 &
sleep 5 &
wait

This is the simplest version of what I was thinking of, I guess.这是我想的最简单的版本,我猜。 Usage in my case would be:在我的情况下,用法是:

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

This works, just feels like there's still something simpler.这行得通,只是感觉还有更简单的东西。

#!/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)

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

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