Чому "sudo cp" не може знайти файли?


7

Хто може дати мені логічне пояснення цього питання:

Я не можу виконати цю команду:

sudo cp /data/*20150522* /backup/

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

І коли я переходжу на root його роботу без проблем.

Я впевнений, що мова йде про те, щоб мати права привілеїв перераховувати файли всередині каталогу / даних, які мають наступні права доступу:

drwxrwx--- 1 root root 

Але ось я запускаю команду з sudo, і в чому тут проблема?


1
Якщо ви не є членом rootгрупи, вона не має дозволу перераховувати каталог. Вам знадобиться, щоб принаймні 751( drwxrwx--x) для некорінного користувача перелічував каталог.
Майкл

1
Offtopic, а не питання програмування.

@Michael Додавання членів до rootгрупи звучить дивно і є потенційним ризиком для безпеки, оскільки root повинен бути дуже обережним, створюючи щось у файловій системі. Я б використовував для цього спеціальну групу admin. Якщо мені chown root:admin somethingне потрібно особливо піклуватися.
hek2mgl

1
@ hek2mgl О, це точно - я не мав на увазі, що користувач повинен бути доданий, просто, що поточні фізичні речовини не працюватимуть.
Майкл

@Michael Так, зрозумів. Просто хотів додати це. :)
hek2mgl

Відповіді:


18

Оболонка намагається розширити глобальну картину, перш ніж вона передасть розширений результат cp(фактично передає результат, до sudoякого потім передає його незмінним cp). Оскільки оболонка (вона працює як ви, а не root) не в змозі пройти каталог, в cpкінцевому підсумку отримує нерозширений візерунок у своєму списку аргументів.

cpне виконує жодного глобального розширення. Він очікує список імен файлів. Рядок із візерунком у ньому не називає файл.

Мабуть, самий прямий спосіб виконання завдання - викликати свою команду в підрозділі. Котируйте команду або подвійними лапками ( "), або одинарними ( ').

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

Це працює, тому що підрозділ розширює шаблон шаблону в командному рядку перед тим, як викликати команду. Оскільки під-оболонка працює як root під sudo, розширення успішно.

Використання подвійних лапок для цитування команди до підкошти дозволяє батьківській оболонці розширити змінні оболонки перед викликом sudoкоманди. Якщо ви хочете, щоб змінні були розширені за допомогою підколі, замість цього слід використовувати одинарні лапки. У цьому випадку вона рівнозначна, оскільки у вас немає змінних. Але, ви можете додати його, щоб побачити різницю в поведінці.

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

Перша команда відображатиме ваше ім'я користувача, тоді як друга команда відображатиме ім'я користувача root.


1
Чи можна якось обробити цю поведінку? sudo <something>з розширенням символів із підвищеними привілеями.
Євген Ш.

1
Може щось sudo bash -c 'cp /data/*foo* /dest'замість цього?
Зоредаче

@Zoredache: Я щойно думав про це, перш ніж читати ваш коментар. Дякую.
jxh

Я думаю , що ви помиляєтеся з "VS '. Жоден з них не розширить *, різниця полягає в розширенні змінних оболонок (спробуйте з "$UID"і '$UID').
rodrigo

@rodrigo: Ти прав, я оновив відповідь. Я знав про розширення змінної оболонки, але чомусь я очікував, що це буде дотримано і для глобального розширення.
jxh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.