我希望通过 ssh 进入远程服务器并运行一系列命令(例如一些随机命令)
touch foo.txt
echo 'bar' > foo.txt
cd ..
ls
并保持这种联系。
有人建议我使用ssh -t $server "commands; bash"
。它确实有效,但它将我带到了与直接使用 不同的目录中ssh $server
。有人知道为什么会发生这种情况吗?
(我正在研究 repo 中现有的代码,所以我想知道是什么机制使得这种情况发生以及为什么)
答案1
知道为什么会发生这种情况吗?
也许您的commands
包括cd
。您正在执行commands; bash
,因此bash
从任何目录commands
结尾开始。
显而易见的解决方案是cd
在调用之前返回bash
。尝试
ssh -t $server 'commands; cd "$HOME"; exec bash -l'
笔记:
- 单引号可防止
$HOME
局部扩展;如果您需要commands
包含局部扩展的变量,请混合使用引号(例如"commands with $var; "'cd "$HOME"; exec bash -l'
)。 exec
,因为您不再需要远程端的父 shell(或者您需要吗?)。-l
(相当于--login
)因为 solessh $server
会生成一个登录 shell,而您希望整个命令都以相同的方式运行。Bash 作为登录 shell 时获取的文件与作为非登录 shell 时获取的文件不同,以 开头/etc/profile
;规则有些复杂,请参阅man 1 bash
,查找INVOCATION
。如果其中一个文件执行cd
到另一个目录,即使commands
不更改目录,您也会得到您得到的结果。您没有说明目录(“正确”的和“错误”的)是什么,因此很难猜测这个“隐藏”的用途cd
是什么。
或者您可以commands
在子 shell 中运行。这不会影响父 shell 的工作目录,因此bash
将从父 shell 启动的位置启动:
ssh -t $server '(commands); exec bash -l'
您可能更喜欢其中一种解决方案,具体取决于要做什么commands
。例如,如果commands
修改远程端 shell 的环境,那么是否在子 shell 中运行它们会对最终结果产生影响bash
。