谁能给我一个合理的解释来解释这个问题:
我无法运行此命令:
sudo cp /data/*20150522* /backup/
cp: cannot stat `/data/*20150522*': No such file or directory
当我切换到 root 时,它可以正常工作。
我确信这与拥有正确的权限有关,以列出 /data 目录中具有以下访问权限的文件:
drwxrwx--- 1 root root
但是这里我使用 sudo 运行命令,那么这里的问题是什么?
答案1
shell 尝试扩展 glob 模式,然后将扩展结果传递给cp
(实际上,它将结果传递给sudo
然后将其不加改变地传递给cp
)。由于 shell(它以您的身份运行,而不是 root)无法遍历目录,cp
因此最终在其参数列表中收到未扩展的模式。
cp
本身不执行任何 glob 扩展。它需要文件名列表。带有模式的字符串不命名文件。
执行该任务最直接的方法可能是在子 shell 中调用命令。使用双引号 ( "
) 或单引号 ( '
) 引用命令。
sudo sh -c "cp /data/*20150522* /backup/"
sudo sh -c 'cp /data/*20150522* /backup/'
这是因为子 shell 在调用命令之前会扩展命令字符串中的 glob 模式。由于子 shell 以 root 身份在 下运行sudo
,因此扩展成功。
使用双引号将命令引用到子 shell 中,可让父 shell 在调用命令之前扩展 shell 变量sudo
。如果您希望子 shell 扩展变量,则应改用单引号。在这种情况下,这是等效的,因为您没有任何变量。但是,您可以添加一个来查看行为的差异。
sudo sh -c "echo $USER; cp /data/*20150522* /backup/"
sudo sh -c 'echo $USER; cp /data/*20150522* /backup/'
第一个命令将显示您的用户名,而第二个命令将显示root用户名。