sudo at -f

sudo at -f

Если я сделаю:

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)

Флаг -Cfor sudoпредлагает другой способ, но для его разрешения может потребоваться дополнительная настройка:

-C число, --close-from=число
Закройте все файловые дескрипторы, большие или равные num, перед выполнением команды. Значения меньше трех не допускаются. По умолчанию sudo закроет все открытые файловые дескрипторы, кроме стандартного ввода, стандартного вывода и стандартной ошибки, при выполнении команды. Политика безопасности может ограничивать возможность пользователя использовать эту опцию. Политика sudoers разрешает использование опции -C только в том случае, если администратор включил опцию closefrom_override.

решение2

Я предполагаю, что вы намерены сделать catвсе файлы root вашего текущего ls?

Может быть разумнее использовать xargsвместо этого pipe. Попробуйте это:

ls | xargs sudo cat

Связанный контент