通过 SSH 连接发送终端命令:嵌套管道

通过 SSH 连接发送终端命令:嵌套管道

大家好,

我目前在通过命令行通过 SSH 向服务器发送命令时遇到问题。举一个简单的例子,我总是发送“pwd”命令 - 它应该返回你当前所在的文件夹。

我使用以下命令成功建立了初始 SSH 连接:

sshg3 user@server#port 'pwd'

它连接到服务器并缩短主文件夹。

之后,我使用 sudo su - user2 - 因为该用户拥有更多用户权限(特定任务所需):

sshg3 user@server#port "echo pwd|sudo su - user2"

但是,在这里,如果我想将多个命令连接在一起,我需要插入“” - 否则它不起作用:

sshg3 user@server#port "echo ""pwd;pwd""|sudo su - user2"

如果我没有或者只有一个“,结果就是:

pwd
-bash: line 1: {homefolder}: is a directory

现在,使用 lftp 之后,我需要使用另一个用户将数据上传到该服务器。使用另一个管道,我可以通过以下方式使用单个命令来实现这一点:

sshg3 user@server#port "echo ""echo pwd|lftp -u user3 -p 1234 server2""|sudo su - user2"

现在问题来了:向第二台服务器发送多个命令不起作用。如果我使用之前使用的相同模式(“”),我会得到以下结果:

sshg3 user@server#port "echo ""echo ""pwd;pwd""|lftp -u user3 -p 1234 server2""|sudo su - user2"

这将打印:

echo pwd
bash: pwd|lftp -u user3 -p 1234 server2: command not found

我通过使用[这个][1]线程中的答案得到了大部分信息 - 但现在我陷入了困境。

有人可以帮我弄这个吗?

答案1

我不太清楚您想在远程服务器上做什么。看起来您想执行依赖于其他命令响应的命令(例如pwd,打印工作目录)。可能您还想为使用密码(“echo pwd”)su,我不确定是哪一个。

我建议采用以下方法之一:

  • 在远程服务器上编写一个脚本,执行您想要的操作。通过ssh执行该脚本。调用脚本时,将密码等附加信息作为参数提供给脚本。

  • 如果您无法将脚本永久存储在远程服务器上:无论如何都要编写脚本,然后通过管道传输并执行整个脚本ssh

  • 使用expect通过 编写一个复杂的交互式会话脚本ssh,您可以在其中调用各种程序,而这些程序又需要用户输入。

无论如何,我认为你不会在这件事上取得很大进展echo

答案2

我认为你有一个XY问题。如果你能告诉我们你想要实现什么,而不是如何您正在尝试实现它,那么我们或许可以提供帮助...


与此同时,由于我无法帮助您解决最初的问题,因此我们来处理以下问题:

sshg3 user@server#port "echo ""echo ""pwd;pwd""|lftp -u user3 -p 1234 server2""|sudo su - user2"

Bash 将根据未引用的空格将其分解为参数,因此参数为:

  1. sshg3
  2. user@server#port
  3. "echo ""echo ""pwd;pwd""|lftp -u user3 -p 1234 server2""|sudo su - user2"

从参数 3 中删除引用后,它将看起来像这样:(我不认为这是你想要的)

echo echo pwd;pwd|ltfp -u user3 -p 1234 server2|sudo su - user2

您可以使用以下代码片段确认这一点。

将您的命令放入数组中X=( YOUR_COMMAND )

$ X=(sshg3 user@server#port "echo ""echo ""pwd;pwd""|lftp -u user3 -p 1234 server2""|sudo su - user2")
$ for i in "${X[@]}"; do echo "${i}"; done
sshg3
user@server#port
echo echo pwd;pwd|lftp -u user3 -p 1234 server2|sudo su - user2

参数 3 的清理版本将被传递到远程系统,并且(可能)将被解释如下:

  • 命令 1 参数:

    1. echo
    2. echo
    3. pwd
  • 命令 2 的参数:(通过管道符 /stdout连接到命令 3 )stdin|

    1. pwd
  • 命令 3 参数:(stdout连接到命令 4 stdin
    1. lftp
    2. -u
    3. user3
    4. -p
    5. 1234
    6. server2
  • 命令 4 参数:
    1. sudo
    2. su
    3. -u
    4. user2

再次,您可以通过从远程 shell 登录并运行清理后的第三行来确认这一点。


关于这一点,有几点需要注意:

  • 您可能不是想将其回显echo pwd到标准输出(这是命令 1 将执行的操作)
  • lftp不会期望给出绝对路径(仅此而已)stdin
  • sulftp很可能不会想到会给出什么输出stdin...su将会调用user2的 shell。

相关内容