
Если я сделаю:
at -f <(echo "rm $file") now + 2 hours
это работает отлично
Однако если я сделаю это:
sudo at -f <(echo "rm $file") now + 2 hours
Я получил:
at: /dev/fd/63: No such file or directory
Я предполагаю, что это из-за порядка обработки команд. Есть ли способ обойти это с помощью команды sudo? Единственный способ, который я могу придумать, это поместить команду в скрипт и sudo этого скрипта, что является опцией, но теперь я хочу узнать, почему это происходит.
Извините, если ответ на этот вопрос уже был где-то, я просто не могу его найти, так как не знаю, что искать.
решение1
Потому что оболочка открывает канал к команде в <(...)
, и передает дескриптор файла дочернему процессу, который он запускает, sudo
в этом случае. Путь /dev/fd/63
— это метод, предоставляемый ядром, чтобы разрешить доступ к уже открытому дескриптору файла через обычное имя пути.
Однако sudo
не передает дескриптор процессу, который он запускает (из соображений безопасности): по умолчанию он закрывает все дескрипторы файлов, кроме stdin, stdout и stderr, поэтому программа, которая в конечном итоге запускается, не имеет соответствующего дескриптора файла /dev/fd/63
и завершается ошибкой.
Решить эту проблему можно, выполнив замену в оболочке внутри sudo:
sudo bash -c 'cat <(echo something)'
Это, конечно, означает, что внутренняя подстановка также выполняется с повышенными привилегиями:
$ sudo bash -c 'cat <(id)'
uid=0(root) gid=0(root) groups=0(root)
Флаг -C
for sudo
предлагает другой способ, но для его разрешения может потребоваться дополнительная настройка:
-C число, --close-from=число
Закройте все файловые дескрипторы, большие или равные num, перед выполнением команды. Значения меньше трех не допускаются. По умолчанию sudo закроет все открытые файловые дескрипторы, кроме стандартного ввода, стандартного вывода и стандартной ошибки, при выполнении команды. Политика безопасности может ограничивать возможность пользователя использовать эту опцию. Политика sudoers разрешает использование опции -C только в том случае, если администратор включил опцию closefrom_override.
решение2
Я предполагаю, что вы намерены сделать cat
все файлы root вашего текущего ls
?
Может быть разумнее использовать xargs
вместо этого pipe. Попробуйте это:
ls | xargs sudo cat