Por que o “sudo cp” não consegue encontrar os arquivos?

Por que o “sudo cp” não consegue encontrar os arquivos?

Quem pode me dar uma explicação lógica para esse problema:

Não consigo executar este comando:

sudo cp /data/*20150522* /backup/

cp: cannot stat `/data/*20150522*': No such file or directory

E quando mudo para o root, ele funciona sem problemas.

Tenho certeza de que se trata de ter os privilégios corretos para listar os arquivos dentro do diretório /data que possuem os seguintes privilégios de acesso:

drwxrwx--- 1 root root 

Mas aqui estou executando o comando com sudo, então qual é o problema aqui?

Responder1

O shell tenta expandir o padrão glob antes de passar o resultado expandido para cp(na verdade, ele está passando o resultado para sudoo qual o passa inalterado para cp). Como o shell (está rodando como você, não como root) não consegue percorrer o diretório, cpacaba recebendo o padrão não expandido em sua lista de argumentos.

cpnão executa nenhuma expansão glob por si só. Espera uma lista de nomes de arquivos. A string com o padrão não nomeia um arquivo.

Talvez a maneira mais direta de executar a tarefa seja invocar seu comando em um subshell. Cite o comando entre aspas duplas ( ") ou aspas simples ( ').

sudo sh -c "cp /data/*20150522* /backup/"
sudo sh -c 'cp /data/*20150522* /backup/'

Isso funciona porque o subshell expande o padrão glob na string de comando antes de invocar o comando. Como o subshell está sendo executado como root em sudo, a expansão foi bem-sucedida.

Usar aspas duplas para citar o comando no subshell permite que o shell pai expanda as variáveis ​​do shell antes de invocar o sudocomando. Se você deseja que as variáveis ​​sejam expandidas pelo subshell, as aspas simples devem ser usadas. Nesse caso é equivalente, pois você não possui nenhuma variável. Mas você pode adicionar um para ver a diferença de comportamento.

sudo sh -c "echo $USER; cp /data/*20150522* /backup/"
sudo sh -c 'echo $USER; cp /data/*20150522* /backup/'

O primeiro comando exibirá seu nome de usuário, enquanto o segundo comando exibirá o nome de usuário root.

informação relacionada