为什么“sudo cp”找不到文件?

IMA*_*_tn 8 linux unix

谁能给我一个合乎逻辑的解释这个问题:

我无法运行此命令:

sudo cp /data/*20150522* /backup/

cp: cannot stat `/data/*20150522*': No such file or directory
Run Code Online (Sandbox Code Playgroud)

当我切换到 root 时,它的工作没有问题。

我确定这是关于拥有正确的权限来列出 /data 目录中具有以下访问权限的文件:

drwxrwx--- 1 root root 
Run Code Online (Sandbox Code Playgroud)

但是在这里我用 sudo 运行命令,那么这里有什么问题呢?

jxh*_*jxh 19

shell 在将扩展结果传递给 之前尝试扩展 glob 模式cp(实际上,它正在传递结果sudo,然后将其原封不动地传递给cp)。由于外壳程序(它以您的身份运行,而不是以 root 身份运行)无法遍历目录,因此cp最终在其参数列表中接收到未扩展的模式。

cp本身不执行任何 glob 扩展。它需要一个文件名列表。包含模式的字符串不命名文件。

也许执行任务最直接的方法是在子 shell 中调用您的命令。用双引号 ( ") 或单引号 ( ')引用命令。

sudo sh -c "cp /data/*20150522* /backup/"
sudo sh -c 'cp /data/*20150522* /backup/'
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为子 shell 在调用命令之前扩展了命令字符串中的 glob 模式。由于子shell在 下以root身份运行sudo,因此扩展成功。

使用双引号将命令引用到子 shell 允许父 shell 在调用sudo命令之前扩展 shell 变量。如果您希望子 shell 扩展变量,则应改用单引号。在这种情况下,它是等效的,因为您没有任何变量。但是,您可以添加一个以查看行为的差异。

sudo sh -c "echo $USER; cp /data/*20150522* /backup/"
sudo sh -c 'echo $USER; cp /data/*20150522* /backup/'
Run Code Online (Sandbox Code Playgroud)

第一个命令将显示您的用户名,而第二个命令将显示 root 用户名。