我正在尝试在通过SSH启动的shell中执行命令,但保持shell打开。我知道通常shell关闭,所以这需要解决,但是我对这样做的简单方法不太满意,例如:
ssh server -t "TheCommand ; bash -i"
首先,该命令随后在ps输出中可见,命令在bash subshell启动之前执行,我更愿意在最终的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登录相同。
应该做什么:
然而,看起来恢复的流由于某种原因无效,我不知道如何解决这个问题,我尝试了很多东西(例如恢复到/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 -l
或bash -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中修复某种程度上?
修改
正如一些评论指出的那样,我应该更好地描述我想要解决的问题。
在原则上,我正在努力实现的是开发一个脚本:
一个问题是安全问题(显示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
在某种程度上起了作用。
有没有更好的方法来做到这一点?