使用“ssh”执行带有星号字符(“*”)的“mv”命令

使用“ssh”执行带有星号字符(“*”)的“mv”命令

我对 Linux 没有经验,但我每天都在学习。

我有这个命令。

ssh admin@$host mv repo/environments/qa/* /repo

这个*字符是否意味着environments/qa目录中的所有内容都将放入该/repo目录中?如果它已经存在,它会取代它吗?

抱歉,我对 shell 命令缺乏经验。我只是想确认一下。

答案1

翻译成另一种语言:

ssh admin@$host mv repo/environments/qa/* /repo

shell 命令(假设是 POSIX shell,例如 sh 或 bash),如下所示:

execute("ssh", glob(split("admin@" + $host)), "mv", glob("repo/environments/qa/*"), "/repo");

(基于 的字符进行拆分$IFS,但仅基于 扩展的部分$host;就像 if $hostismachine$IFScontains一样anadmin@machine将被拆分为admin@m, chi, 和e,字面量中的a和不受拆分)。nadmin

虽然您希望它是:

execute("ssh", "admin@" + $host, "mv repo/environments/qa/* /repo")

shell 中的语法为:

ssh admin@"$host" 'mv repo/environments/qa/* /repo'

ssh会将该mv repo/environment/qa/* /repo字符串传递到sshd远程服务器上,以便将其传递到远程用户的登录 shell 进行解释,通常为:

execute("that-shell", "-c", "mv repo/environments/qa/* /repo")

在大多数 shell 中,这相当于:

execute("mv", glob("repo/environments/qa/*"), "/repo")

告诉mv移动所有非隐藏文件(任何类型,包括目录)内repo/environments/qa(本身是相对于 shell 进程当前工作目录的路径,该进程sshd应已初始化为用户的主目录)到/repo1。

从中可以得出一些结论:

  • 像上面这样的参数扩展$host几乎必须总是被引用以避免 split+glob。

  • 您希望远程系统上的 shell 扩展该 glob,因此*必须按字面传递。

  • 重要的是要记住,ssh远程解释 shell 代码并不运行简单的命令。如果传递多个参数,它将用空格将它们连接起来以组成要传递到远程 shell 的代码,但我建议您仅传递一个代码参数,如果只是为了提醒它是 shell 代码而不是简单的命令,并且远程 shell 语法中的任何特殊字符都将被视为此类字符。

    例如,不要 do ssh host echo *.txt,因为这*.txt将由本地 shell 扩展,并且如果foo;reboot #.txt当前工作目录中有一个文件被调用,那么这将导致execute("ssh", "host", "echo", "foo;reboot #.txt")完成,然后sshd运行execute("sh", "-c", "echo foo;reboot #.txt")并重新启动。


¹ 请注意 if/repo确实存在或不是类型目录(或目录的符号链接)并repo/environments/qa/*扩展为仅一个文件,该文件将是重命名,搬去(相对于搬进/repo;更改/repo为可以避免该问题,如果不是目录则/repo/报告错误。/repo

相关内容