この問題について論理的な説明をしてくれる人はいますか?
このコマンドは実行できません:
sudo cp /data/*20150522* /backup/
cp: cannot stat `/data/*20150522*': No such file or directory
そして、ルートに切り替えると問題なく動作します。
これは、次のアクセス権限を持つ /data ディレクトリ内のファイルを一覧表示するための適切な権限を持つことに関するものであると確信しています。
drwxrwx--- 1 root root
しかし、ここでは sudo を使用してコマンドを実行しているので、ここでの問題は何でしょうか?
答え1
シェルは、展開された結果を に渡す前に、glob パターンの展開を試みますcp
(実際には、 に結果を渡し、sudo
そこから変更せずに に渡しますcp
)。シェル (root ではなくユーザーとして実行) はディレクトリをトラバースできないため、cp
展開されていないパターンが引数リストに残ります。
cp
自体は glob 展開を実行しません。ファイル名のリストを期待します。パターンを含む文字列はファイルの名前にはなりません。
おそらく、このタスクを実行する最も簡単な方法は、サブシェルでコマンドを呼び出すことです。コマンドを二重引用符 ( "
) または一重引用符 ( '
) で囲みます。
sudo sh -c "cp /data/*20150522* /backup/"
sudo sh -c 'cp /data/*20150522* /backup/'
これが機能するのは、サブシェルがコマンドを呼び出す前にコマンド文字列内の glob パターンを展開するためです。サブシェルは の下で root として実行されているためsudo
、展開は成功します。
二重引用符を使用してサブシェルにコマンドを引用すると、親シェルはコマンドを呼び出す前にシェル変数を展開できますsudo
。サブシェルで変数を展開したい場合は、代わりに一重引用符を使用する必要があります。この場合、変数がないので、同じです。ただし、動作の違いを確認するために変数を追加することもできます。
sudo sh -c "echo $USER; cp /data/*20150522* /backup/"
sudo sh -c 'echo $USER; cp /data/*20150522* /backup/'
最初のコマンドはユーザー名を表示し、2 番目のコマンドはルート ユーザー名を表示します。