SSH:执行命令并保持shell打开

时间:2016-01-06 13:27:06

标签: linux bash shell ssh

我正在尝试在通过SSH启动的shell中执行命令,但保持shell打开。我知道通常shell关闭,所以这需要解决,但是我对这样做的简单方法不太满意,例如:

ssh server -t "TheCommand ; bash -i"

首先,该命令随后在ps输出中可见,命令在bash subshel​​l启动之前执行,我更愿意在最终的shell中启动它 - 该命令应该设置自定义环境shell,如果在启动final(sub)shell之前设置了环境,则RC配置文件可以覆盖环境变量(如果变量名称与RC中设置的变量相同)。

我发现我可以使用heredoc,所以我带来了这个(解决方案#1 ):

ssh server -tt 3<<SCRIPT 4<&0 <&3
TheCommand
exec 3>&- <&4
SCRIPT

不幸的是,它无法正常工作:在线

exec 3>&- <&4

报告了以下错误:

-bash: 4: Bad file descriptor

并且shell保持打开状态,但它不能接受任何输入(只有Ctrl + C可以退出ssh shell)。除此之外,脚本被执行,如果我将ps ax | grep bash添加到脚本中,它会显示:

15054 pts/15   Ss     0:00 -bash
15109 pts/15   S+     0:00 grep bash

这将是完美的,因为它与常规的ssh登录相同。

应该做什么:

  1. 将heredoc脚本读取到自定义文件描述符3上(因为如果使用常规输入描述符,则在脚本完成后shell将终止。)
  2. 将原始stdin流(0)复制到自定义流4中。
  3. 将stdin重定向到fd 3以读取heredoc脚本。
  4. 在heredoc脚本结束时,将输入流恢复为原始流(即将存储的fd 4复制回0)。
  5. 然而,看起来恢复的流由于某种原因无效,我不知道如何解决这个问题,我尝试了很多东西(例如恢复到/dev/tty$(tty),其中有效 - 它不会报告无效的流并保持shell打开,但除了Ctrl + C退出外,我仍然无法执行任何操作。

    我怀疑当我将stdin重定向到&amp; 3时,ssh或bash会关闭标准的stdin流(或根本不打开/分配它)所以当我尝试将其恢复时,它是无效的。 / p>

    有没有可能解决这个问题?因为那是我的首选解决方案。

    通过明确地运行bash,我找到了一种方法来解决这个问题(解决方案#2 ):

    ssh server -t "bash -i 3<<SCRIPT 4<&0 <&3
    TheCommand
    exec 3>&- <&4
    SCRIPT
    "
    

    这有效,但并不完全理想。有一件事是,它不是登录shell(并且它不适用于bash -lbash -l -i),并且在此类shell中运行ps ax | grep bash时,它提供以下内容: / p>

    15234 pts/15   Ss     0:00 bash -c bash -i 3<<SCRIPT 4<&0 <&3?TheCommand?exec 3>&- <&4?SCRIPT?
    15262 pts/15   S      0:00 bash -i
    15282 pts/15   S+     0:00 grep bash
    

    这不太好(整个脚本在列表中可见,与开头的简单解决方案一样)。

    然而,这里stdin(&amp; 0)的存储和恢复效果很好。我想知道为什么它在解决方案#2 中工作,而不是在解决方案#1 中工作,如果它可以在解决方案#1中修复某种程度上?

    修改

    正如一些评论指出的那样,我应该更好地描述我想要解决的问题。

    在原则上,我正在努力实现的是开发一个脚本:

    • 连接到SSH远程计算机
    • 将远程目录更改为脚本确定的位置
    • 在远程shell中设置一些环境变量(请注意,它可能需要覆盖来自配置文件或bashrc的变量;并且需要运行profile / bashrc脚本来设置,例如命令提示符等。)
    • 保持ssh会话打开,以便操作员可以在之后发出更多命令(具体设置shell)

    一个问题是安全问题(显示ps输出中的整个命令),另一个问题是在启动最终shell之前设置env变量时,它们被profile / bashrc覆盖(包含一些默认值) )。

    到目前为止,我目前最好的解决方案是:

    ssh server -t "cd /ThePath ; exec \$SHELL -i 3<<ENV 4<&0 <&3
    export THE_VARIABLE=TheValue
    exec 3>&- <&4
    ENV
    "
    

    这样,变量在加载配置文件后设置,因此似乎可以工作。此外,ps ax输出相对较好:

    17604 pts/15   Ss     0:00 /bin/bash -i
    17654 pts/15   S+     0:00 grep bash
    

    所以似乎exec在某种程度上起了作用。

    有没有更好的方法来做到这一点?

0 个答案:

没有答案