通过 ssh 有条件地运行子进程,同时将输出附加到(可能是远程)文件

我有一个可以在我的主机和其他几台服务器上运行的脚本。我想使用 ssh 将此脚本作为我的主机上的后台进程与远程计算机一起启动,并将 stdout/stderr 输出到主机以用于我的主机后台进程,并输出到远程计算机以用于远程计算机后台任务。

我尝试过

subprocess.check_output(['python' ,'script.py' ,'arg_1', ' > file.log ', ' & echo -ne $! ']

但它不起作用。它不给我 pid 也不写入文件。它可以工作shell=True,但后来我读到出于安全原因使用 shell=True 不好。

然后我尝试了

p = subprocess.Popen(['python' ,'script.py' ,'arg_1', ' > file.log ']

现在我可以获得进程 pid,但输出没有写入远程日志文件。

使用下面建议的 stdout/stderr 参数将在我的主机而不是远程计算机中打开日志文件。

有人可以建议我一个既可以在我的主机上工作,也可以通过 ssh 连接到远程服务器并在那里启动后台进程的命令吗?并写入输出文件?

<HOW_TO_GET_PID> = subprocess.<WHAT>( ([] if 'localhost' else ['ssh','<remote_server>']) + ['python', 'script.py', 'arg_1' <WHAT>] )

有人可以完成上面的伪代码吗?


隔江千里
浏览 224回答 2
2回答

慕盖茨4494581

你不可能在一行行中得到安全、正确的东西而不使其不可读。最好不要尝试。请注意,我们在这里使用 shell:在本地情况下,我们显式调用shell=True,而在远程情况下ssh,总是隐式启动 shell。import shleximport subprocessdef startBackgroundCommand(argv, outputFile, remoteHost=None, andGetPID=False):&nbsp; &nbsp; cmd_str = ' '.join(shlex.quote(word) for word in argv)&nbsp; &nbsp; if outputFile != None:&nbsp; &nbsp; &nbsp; &nbsp; cmd_str += ' >%s' % (shlex.quote(outputFile),)&nbsp; &nbsp; if andGetPID:&nbsp; &nbsp; &nbsp; &nbsp; cmd_str += ' & echo "$!"'&nbsp; &nbsp; if remoteHost != None:&nbsp; &nbsp; &nbsp; &nbsp; p = subprocess.Popen(['ssh', remoteHost, cmd_str], stdout=subprocess.PIPE)&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; p = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, shell=True)&nbsp; &nbsp; return p.communicate()[0]# Run your command locallystartBackgroundCommand(['python', 'script.py', 'arg_1'],&nbsp; &nbsp; outputFile='file.log', andGetPID=True)# Or run your command remotelystartBackgroundCommand(['python', 'script.py', 'arg_1'],&nbsp; &nbsp; remoteHost='foo.example.com', outputFile='file.log', andGetPID=True)

蓝山帝景

# At the beginning you can even program automatic daemonizing# Using os.fork(), otherwise, you run it with something like:# nohup python run_my_script.py &# This will ensure that it continues running even if SSH connection breaks.from subprocess import Popen, PIPE, STDOUTp = Popen(["python", "yourscript.py"], stdout=PIPE, stderr=STDOUT, stdin=PIPE)p.stdin.close()log = open("logfile.log", "wb")log.write(b"PID: %i\n\n" % p.pid)while 1:&nbsp; &nbsp; line = p.stdout.readline()&nbsp; &nbsp; if not line: break&nbsp; &nbsp; log.write(line)&nbsp; &nbsp; log.flush()p.stdout.close()log.write(b"\nExit status: %i" % p.poll())log.close()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python