Python 在资源有限的计算机上启动子进程 编辑:
这个问题的初衷是找到一种通过Python脚本启动交互式Python 在资源有限的计算机上启动子进程 编辑:,python,bash,ssh,Python,Bash,Ssh,这个问题的初衷是找到一种通过Python脚本启动交互式ssh会话的方法。我以前尝试过subprocess.call(),在任何东西输出到终端之前,我得到了一个Killed响应。我只是假设这是子流程模块的一个问题/限制,而不是其他地方的问题。当我在非资源有限的机器上运行脚本时,发现情况并非如此,它工作正常 这就把问题变成了:我怎样才能在任何资源限制阻止它运行的情况下运行交互式ssh会话 向查尔斯·达菲喊道,他在试图诊断这一切时帮了大忙 以下是原问题: 背景: 所以我有一个脚本,目前是用bash编写
ssh
会话的方法。我以前尝试过subprocess.call()
,在任何东西输出到终端之前,我得到了一个Killed
响应。我只是假设这是子流程
模块的一个问题/限制,而不是其他地方的问题。当我在非资源有限的机器上运行脚本时,发现情况并非如此,它工作正常
这就把问题变成了:我怎样才能在任何资源限制阻止它运行的情况下运行交互式ssh
会话
向查尔斯·达菲喊道,他在试图诊断这一切时帮了大忙
以下是原问题:
背景:
所以我有一个脚本,目前是用bash编写的。它解析一些控制台函数的输出,然后根据这些解析的输出打开ssh会话
它目前运行良好,但我想通过添加一些标志参数来扩展它的功能。我以前使用过argparse
,非常喜欢它。我试着在bash中做一些标记工作,我们可以说它还有很多需要改进的地方
实际问题是:
有没有可能让python在控制台中执行任务,然后将用户放在该控制台中?
类似于使用子流程
在当前查看的控制台上运行一系列命令?这与子流程
通常的运行方式不同,它运行命令,然后关闭中间控制台
具体示例,因为我不确定我所描述的内容是否有意义:
下面是我想要的功能的基本概述:
ssh-t$correctnode“cd/local\u scratch/pbs.$jobid;bash-l”
$correctnode
,更改目录,然后使该节点中的bash窗口保持打开状态
我已经知道如何做第1部分和第2部分了。第三部分我搞不懂。任何帮助都将不胜感激
编辑:与之不同的是,我不是仅仅尝试运行命令。我试图显示一个由命令创建的shell。具体来说,我想显示一个通过
ssh
命令创建的bash shell。这绝不是一个真正的答案,只是对我的评论的一个说明
假设您有一个Python脚本,test.py:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('myarg', nargs="*")
args = parser.parse_args()
print("echo Hello world! My arguments are: " + " ".join(args.myarg))
因此,在它周围创建一个bash包装器,test.sh
set -e
$(python test.py $*)
这就是你得到的:
$ bash test.sh
Hello world! My arguments are:
$ bash test.sh one two
Hello world! My arguments are: one two
这里发生了什么:
- python脚本不执行命令。相反,它输出bash脚本将运行的命令(本例中为echo)。在您的情况下,最后一个命令是
ssh blablabla
- bash执行python脚本的输出(
部分),传递它的所有参数($(…)
部分)$*
- 可以在python脚本中使用argparse;如果参数有任何错误,消息将被放入stderr,而不会由bash执行;bash脚本将停止,因为
标志set-e
ssh
进程作为python
的子进程超过了相关限制(可能是进程数)
方法A:用交互式进程替换Python解释器 使用系统调用的
exec*()
系列会导致原始进程不再位于内存中(不同于fork()+exec*()
组合用于在保持父进程运行时启动子进程),因此它不计入帐户限制
import argparse
导入操作系统
尝试:
从shlex进口报价
除恐怖外:
从管道导入报价
parser=argparse.ArgumentParser()
parser.add_参数('node'))
parser.add_参数('jobid')
args=parser.parse_args()
remote_cmd_str='cd/local_scratch/pbs.%s&&exec bash-i'(引号(args.jobid))
本地命令=[
'/usr/bin/env',ssh','-tt',node,remote\u cmd\u str
]
os.execv(“/usr/bin/env”,本地命令)
方法B:从Python生成Shell命令 如果我们使用Python生成shell命令,那么shell只能在Python进程退出后调用该命令,这样我们就不受外部强制的进程限制 首先,在生成
eval
-able输出时,一种稍微稳健一些的方法:
import argparse
尝试:
从shlex进口报价
除恐怖外:
从管道导入报价
parser=argparse.ArgumentParser()
parser.add_参数('node'))
parser.add_参数('jobid')
args=parser.parse_args()
remoteCmd=['cd','/local\u scratch/pbs.%s'(args.jobid)]
remoteCmdStr=''.join(remoteCmd中x的引号(x))+&&bash-l'
cmd=['ssh','-t',args.correctnode,remoteCmdStr]
打印(“”.join(管道.在cmd中x的引号(x))
要从shell运行此命令,如果上面的命令名为genSshCmd
:
!/bin/sh
eval“$(genSshCmd“$@”)
请注意,这里有两个单独的引用层:一个用于运行
eval
的本地shell,另一个用于由SSH启动的远程shell。这很关键——您不希望jobid为$(rm-rf~)
要真正调用rm
你试过这个吗?我试过subprocess.call(['ssh','-t',nodename',bash-l'])时可能重复@hemnathmouli,但它出现了错误
bash:bash-l:找不到命令。不过,我只是键入了ssh-t[nodename]“bash-l”`,它工作得非常好。如果你让它工作并添加你自己的答案演示