Python 在资源有限的计算机上启动子进程 编辑:

Python 在资源有限的计算机上启动子进程 编辑:,python,bash,ssh,Python,Bash,Ssh,这个问题的初衷是找到一种通过Python脚本启动交互式ssh会话的方法。我以前尝试过subprocess.call(),在任何东西输出到终端之前,我得到了一个Killed响应。我只是假设这是子流程模块的一个问题/限制,而不是其他地方的问题。当我在非资源有限的机器上运行脚本时,发现情况并非如此,它工作正常 这就把问题变成了:我怎样才能在任何资源限制阻止它运行的情况下运行交互式ssh会话 向查尔斯·达菲喊道,他在试图诊断这一切时帮了大忙 以下是原问题: 背景: 所以我有一个脚本,目前是用bash编写

这个问题的初衷是找到一种通过Python脚本启动交互式
ssh
会话的方法。我以前尝试过
subprocess.call()
,在任何东西输出到终端之前,我得到了一个
Killed
响应。我只是假设这是
子流程
模块的一个问题/限制,而不是其他地方的问题。当我在非资源有限的机器上运行脚本时,发现情况并非如此,它工作正常

这就把问题变成了:我怎样才能在任何资源限制阻止它运行的情况下运行交互式
ssh
会话

向查尔斯·达菲喊道,他在试图诊断这一切时帮了大忙

以下是原问题:

背景: 所以我有一个脚本,目前是用bash编写的。它解析一些控制台函数的输出,然后根据这些解析的输出打开ssh会话

它目前运行良好,但我想通过添加一些标志参数来扩展它的功能。我以前使用过
argparse
,非常喜欢它。我试着在bash中做一些标记工作,我们可以说它还有很多需要改进的地方

实际问题是: 有没有可能让python在控制台中执行任务,然后将用户放在该控制台中?

类似于使用
子流程
在当前查看的控制台上运行一系列命令?这与
子流程
通常的运行方式不同,它运行命令,然后关闭中间控制台

具体示例,因为我不确定我所描述的内容是否有意义: 下面是我想要的功能的基本概述:

  • 运行python脚本
  • 让脚本运行一些控制台命令并解析输出
  • 运行以下命令:

    ssh-t$correctnode“cd/local\u scratch/pbs.$jobid;bash-l”

  • 此命令将ssh到
    $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
      标志
    读者的上下文 OP是在一个资源非常有限(特别是,它看起来是进程受限)的jumphost框上运行的,在这里启动
    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”`,它工作得非常好。如果你让它工作并添加你自己的答案演示