SSH 进入服务器,启动屏幕会话,更改目录?

Sib*_*ing 4 gnu-screen

我想通过 SSH 连接到服务器,启动屏幕会话,cd进入path/to/my/script/,然后在test.sh那里运行 。

作为初学者,我尝试了

ssh me@myserver.com screen -dm bash -c 'cd  path/to/my/script/; pwd > ~/output.txt'
Run Code Online (Sandbox Code Playgroud)

并希望在 中看到,但我path/to/my/script/output.txt那里看到了我的主目录。这意味着该cd命令实际上不起作用,因此 bash 将无法运行test.sh.

我该如何解决这个问题?

brm*_*brm 5

简短的回答:在命令周围添加一些额外的引号,如下所示:

ssh me@myserver.com "screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'" 
Run Code Online (Sandbox Code Playgroud)

要查看发生了什么,您可以指定-v选项ssh以获取一些调试信息。在这种情况下,对于原始命令,您将看到如下一行

debug1: Sending command: screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt
Run Code Online (Sandbox Code Playgroud)

而额外的引号将其更改为

debug1: Sending command: screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
Run Code Online (Sandbox Code Playgroud)

所以看起来 ssh 只是接受传递给它的参数,将它们全部连接起来,并让远程端再次将连接的参数列表拆分为单个参数。调用参数列表argv(如在 C 中),您在原始版本中得到了如下内容:

argv[0] = ssh
argv[1] = me@myserver.com
argv[2] = screen
argv[3] = -dm
argv[4] = bash
argv[5] = -c
argv[6] = cd path/to/my/script/; pwd > ~/output.txt
Run Code Online (Sandbox Code Playgroud)

现在原则上,可以将to作为单独的参数ssh传递argv[2]argv[6]另一方,在这种情况下,它可能会按预期工作。但是正如调试行所示(并且它似乎也基于源代码),这些参数连接到字符串

screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt
Run Code Online (Sandbox Code Playgroud)

然后在远程端解释。由此也很清楚为什么它不做你想做的事情:现在你正在按顺序执行两件事,首先screen -dm bash -c cd path/to/my/script/(因此screen启动一个会话,其中只更改目录)从主目录执行,然后然后pwd > ~/output.txt也从主目录执行。

为了完整起见,带双引号的命令的参数是

argv[0] = ssh
argv[1] = me@myserver.com
argv[2] = screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
Run Code Online (Sandbox Code Playgroud)

导致screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'发送到另一端(如调试行所示),它按预期工作。