bash - 在非交互式Shell session 中运行多个命令并解析输出

标签 bash shell ssh non-interactive

我想通过其stdin / stdout与(远程)非交互式shell通信,以运行多个命令并读取输出。问题是,如果我在shell stdin上填充多个命令,则无法检测单个命令的输出之间的边界。

在类似Python的伪代码中:

sh = Popen(['ssh', 'user@remote', '/bin/bash'], stdin=PIPE, stdout=PIPE)
sh.stdin.write('ls /\n')
sh.stdin.write('ls /usr\n')
sh.stdin.close()
out = sh.stdout.read()

但是很明显out包含了两个命令的输出,我无法可靠地拆分它们。

到目前为止,我最好的主意是在输出之间插入\0字节:
sh.stdin.write('ls /; echo -ne "\0"\n')
sh.stdin.write('ls /usr; echo -ne "\0"\n')

然后,我可以将out拆分为零个字符。

其他对我不起作用的方法:
  • 我不想为每个命令运行一个单独的ssh session ,因为握手太重了。
  • 我不想在所创建的 shell 上强制使用ControlMaster选项来尊重最终用户的ssh_config。
  • 我希望不需要用户安装特定的服务器程序。

  • 有没有更好的方法可以在一个 session 中运行多个命令并获得单个输出?有没有采用某种二进制输出模式的广泛部署的shell?

    PS。有一个重复的问题,但没有令人满意的答案:
    Run multiple commands in a single ssh session using popen and save the output in separate files

    最佳答案

    对于SSH,我使用了paramiko及其invoke_shell方法来创建可程序管理的shell实例。

    以下不是一个完整的答案,它仍然很笨拙,但我认为这是朝正确方向迈出的一步。

    我在Windows中需要相同的读/写shell实例功能,但是运气不佳,因此我稍微扩展了您的方法(顺便感谢您的想法)。

    我通过在每个命令之间放置一个条件退出来验证每个命令是否基于其退出代码成功执行,然后使用所述条件检查的文本(已知字符串)作为分隔符来定义每个命令的响应。

    一个简单的例子:

    from subprocess import Popen, PIPE
    
    sh = Popen('cmd', stdin=PIPE, stdout=PIPE)
    sh.stdin.write(b'F:\r\n')
    sh.stdin.write(b"if not %errorlevel% == 0 exit\r\n")
    sh.stdin.write(b'cd F:\\NewFolder\r\n')
    sh.stdin.write(b"if not %errorlevel% == 0 exit\r\n")
    sh.stdin.write('...some useful command with the current directory confirmed as set to F:\NewFolder...')
    sh.stdin.close()
    out = sh.stdout.read()
    sh.stdout.close()
    # Split 'out' by each line that ends with 'if not %errorlevel% == 0 exit' and do what you require with the responses
    

    关于bash - 在非交互式Shell session 中运行多个命令并解析输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35849587/

    相关文章:

    git push 在本地 gitlab 存储库上失败

    bash - 如果找到则使用 awk 替换特定列值

    linux - 无论 bash printf 输出如何,都将文本保留在适当的位置

    regex - 当模式包含 "["时,字符串替换不起作用

    bash - 按列合并文本文件 : two column common and append third column form all files

    ssh - 通过 SSH 执行 sudo 的正确方法是什么?

    linux - 使用 "find … -delete"仅从特殊子目录中删除图像文件

    bash - 从 shell 脚本执行 Vim 命令

    windows - msys中的sudo相当于什么?

    python - 将不同服务器上的 MySQL Server 数据库中的表复制到我的计算机