我想通过 SSH 连接到服务器,启动屏幕会话,cd
进入path/to/my/script/
并 test.sh
在那里运行。
作为初学者,我尝试过
ssh [email protected] screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
并期望path/to/my/script/
在 中看到output.txt
,但我在那里看到了我的主目录。这意味着该cd
命令实际上不起作用,因此 bash 将无法运行test.sh
。
我该如何解决这个问题?
答案1
简短的回答:在命令周围添加一些额外的引号,如下所示:
ssh [email protected] "screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'"
要查看发生了什么,您可以指定获取一些调试信息的-v
选项。ssh
在这种情况下,您将看到类似以下的行对于原始命令
debug1: Sending command: screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt
而额外的引号将其更改为
debug1: Sending command: screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
因此,ssh 似乎只是获取传递给它的参数,将它们全部连接起来,然后让远程端再次将连接的参数列表拆分为单独的参数。调用参数列表argv
(就像在 C 中一样),在原始版本中您会得到类似以下内容的内容:
argv[0] = ssh
argv[1] = [email protected]
argv[2] = screen
argv[3] = -dm
argv[4] = bash
argv[5] = -c
argv[6] = cd path/to/my/script/; pwd > ~/output.txt
现在原则上,可以将其作为单独的参数ssh
传递argv[2]
给argv[6]
另一方,在这种情况下,它可能会按预期工作。但正如调试行所示(基于源代码似乎也是如此),这些参数被连接到字符串
screen -dm bash -c cd path/to/my/script/; pwd > ~/output.txt
然后在远程端进行解释。从这里也很清楚为什么它不做你想要的事情:现在你正在按顺序执行两件事,首先screen -dm bash -c cd path/to/my/script/
(因此screen
启动一个会话,其中仅更改目录)从主目录执行,然后thenpwd > ~/output.txt
也是从主目录执行。
为了完整起见,带双引号的命令的参数是
argv[0] = ssh
argv[1] = [email protected]
argv[2] = screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
导致screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'
发送到另一端(如调试行所示),这确实按预期工作。
答案2
@brm 的评论是正确的答案。只需添加额外的双引号即可:
ssh [email protected] "screen -dm bash -c 'cd path/to/my/script/; pwd > ~/output.txt'"