有条件地 运行 通过 ssh 进行子处理,同时将输出附加到(可能是远程的)文件
Conditionally run subprocess over ssh, while appending output to a (potentially remote) file
我有一个脚本可以 运行 在我的主机和其他几台服务器上。我想使用 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 参数将在我的主机而非远程机器中打开日志文件。我想改为登录远程计算机。
append subprocess.Popen output to file?
有人可以向我推荐一个命令,它既可以在我的主机上运行,也可以通过 ssh 连接到远程服务器并在那里启动后台进程吗?并写入输出文件 ?
<HOW_TO_GET_PID> = subprocess.<WHAT>( ([] if 'localhost' else ['ssh','<remote_server>']) + ['python', 'script.py', 'arg_1' <WHAT>] )
有人可以完成上面的伪代码吗?
谢谢,
# 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, STDOUT
p = 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:
line = p.stdout.readline()
if not line: break
log.write(line)
log.flush()
p.stdout.close()
log.write(b"\nExit status: %i" % p.poll())
log.close()
你不会在 one-liner 中得到安全和正确的东西而不让它变得不可读;最好不要尝试。
请注意,我们在这里使用 shell:在本地情况下我们显式调用 shell=True
,而在远程情况下 ssh
始终隐式启动 shell.
import shlex
import subprocess
def startBackgroundCommand(argv, outputFile, remoteHost=None, andGetPID=False):
cmd_str = ' '.join(shlex.quote(word) for word in argv)
if outputFile != None:
cmd_str += ' >%s' % (shlex.quote(outputFile),)
if andGetPID:
cmd_str += ' & echo "$!"'
if remoteHost != None:
p = subprocess.Popen(['ssh', remoteHost, cmd_str], stdout=subprocess.PIPE)
else:
p = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, shell=True)
return p.communicate()[0]
# Run your command locally
startBackgroundCommand(['python', 'script.py', 'arg_1'],
outputFile='file.log', andGetPID=True)
# Or run your command remotely
startBackgroundCommand(['python', 'script.py', 'arg_1'],
remoteHost='foo.example.com', outputFile='file.log', andGetPID=True)
我有一个脚本可以 运行 在我的主机和其他几台服务器上。我想使用 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 参数将在我的主机而非远程机器中打开日志文件。我想改为登录远程计算机。 append subprocess.Popen output to file?
有人可以向我推荐一个命令,它既可以在我的主机上运行,也可以通过 ssh 连接到远程服务器并在那里启动后台进程吗?并写入输出文件 ?
<HOW_TO_GET_PID> = subprocess.<WHAT>( ([] if 'localhost' else ['ssh','<remote_server>']) + ['python', 'script.py', 'arg_1' <WHAT>] )
有人可以完成上面的伪代码吗?
谢谢,
# 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, STDOUT
p = 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:
line = p.stdout.readline()
if not line: break
log.write(line)
log.flush()
p.stdout.close()
log.write(b"\nExit status: %i" % p.poll())
log.close()
你不会在 one-liner 中得到安全和正确的东西而不让它变得不可读;最好不要尝试。
请注意,我们在这里使用 shell:在本地情况下我们显式调用 shell=True
,而在远程情况下 ssh
始终隐式启动 shell.
import shlex
import subprocess
def startBackgroundCommand(argv, outputFile, remoteHost=None, andGetPID=False):
cmd_str = ' '.join(shlex.quote(word) for word in argv)
if outputFile != None:
cmd_str += ' >%s' % (shlex.quote(outputFile),)
if andGetPID:
cmd_str += ' & echo "$!"'
if remoteHost != None:
p = subprocess.Popen(['ssh', remoteHost, cmd_str], stdout=subprocess.PIPE)
else:
p = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, shell=True)
return p.communicate()[0]
# Run your command locally
startBackgroundCommand(['python', 'script.py', 'arg_1'],
outputFile='file.log', andGetPID=True)
# Or run your command remotely
startBackgroundCommand(['python', 'script.py', 'arg_1'],
remoteHost='foo.example.com', outputFile='file.log', andGetPID=True)