Запустите команду, которая требует sudo по прошествии времени

30

Я обычно делаю

sleep 4h; command

выполнить команду через 4 часа. Однако, если эта команда требует sudo, она не будет работать.

Можно ли дать sudoразрешение в тот момент, когда я запускаю sleepкоманду?

ОК Герландо
источник
что-то вроде этого unix.stackexchange.com/questions/391796/…
MatsK
В этом конкретном случае я думаю, что вы можете просто использовать shutdown. команда с sudo и соответствующими аргументами для планирования сна в определенное время.
oarfish
Какую задачу вам нужно сделать, и почему именно 4 часа сна?
Торбьерн Равн Андерсен

Ответы:

46

Используйте sudoдля запуска корневой оболочки, в которой вы запускаете команды:

sudo bash -c 'sleep 4h; command'

Каждая команда, выполняемая в корневой оболочке, выполняется с правами root, что sleepне повредит. Если вам нужно запустить команду с правами пользователя, используйте sudo -u USERNAME COMMAND, например:

$ sudo bash -c 'sleep 4h; sudo -u dessert whoami; whoami'
dessert  # whoami run as user dessert
root     # whoami run as root

Другой подход заключается в том, sudo visudoчтобы разрешить выполнение команды без корневого доступа, см .: Как разрешить выполнение без запроса пароля с использованием sudo?
Обратите внимание, что в зависимости от команды это может создать уязвимость системы безопасности.

Десерт
источник
21

Предполагая, что вы хотите запустить процесс только один раз (не, например, каждые 4 часа), вы можете использовать atd

  1. Убедитесь, что atd работает (в Ubuntu, который есть /etc/init.d/atd statusили еще лучше systemctl status atd)
  2. В терминале от имени root выполните вашу команду следующим образом:

    # at now + 4 hours
    warning: commands will be executed using /bin/sh
    at> command
    at> CTRL-D
  3. Если вы хотите запускать его каждые 4 часа, вы также можете использовать cron (как root) со следующей конфигурацией в вашем crontab

    0 */4 * * * sh -c $'/path/to/command'
Ama Aje My Fren
источник
2
Да, atэто правильный инструмент для этой работы, потому что он также заботится о перенаправлении ввода / вывода, не блокирует окно оболочки и работает, даже когда пользователь вышел из системы или с тех пор машина была перезагружена.
Саймон Рихтер
4
@SimonRichter: sudo bash -c 'sleep 4h && command' &поместить sudo в фоновый режим - это более простой способ не блокировать окно / вкладку оболочки. Если вы хотите, чтобы вывод всплывал асинхронно в качестве напоминания о том, что это произошло, это проще. Он не работает при перезагрузке, но в зависимости от ваших nohupнастроек он может оставаться запущенным после выхода / выхода из оболочки.
Питер Кордес
4
Обратите внимание, что atкоманда запускается, как только она может, когда система приостанавливается в указанное время, см. Здесь на U & L - в зависимости от команды (ей) для выполнения, это может быть не то, что вы хотите.
десерт
2
Просто предложение, вы также можете использовать systemctl для проверки состояния службы вместо прямого вызова этого сценария init.d. Хотя оба, по-видимому, имеют одинаковый результат, я думаю, что современный способ взаимодействия со службами systemd должен быть предпочтительным:systemctl status atd
Byte Commander
15

Одним из способов является запуск через сценарий оболочки с sudoразрешениями (и ввод пароля при запуске сценария оболочки), если сценарий оболочки находится в текущем каталоге,

sudo ./delayer 4h

где delayerможет быть шеллскрипт с содержанием

#!/bin/bash
sleep "$1"
command

Сделайте его исполняемым с

chmod +x delayer

и скопируйте или переместите его в каталог, PATHесли хотите.


Если вы хотите более гибкий сценарий, в котором вы можете выбрать команду [строка] для задержки, введя параметр (ы), вы можете попробовать

#!/bin/bash

if [ $# -lt 2 ] || [ "$(whoami)" != "root" ]
then
 echo "Delay start of command, that needs 'sudo'
Usage:    sudo $0 <delay> <command line>
Example:  sudo $0 4h parted -ls"
 exit
fi

sleep "$1"
shift
"$@"

Демо-пример (короткая задержка, 5 с, для демонстрации),

$ ./delayer
Delay start of command, that needs 'sudo'
Usage:    sudo ./delayer <delay> <command line>
Example:  sudo ./delayer 4h parted -ls

$ sudo ./delayer 5s parted /dev/sdc p
[sudo] password for sudodus: 
Model: Kanguru SS3 (scsi)
Disk /dev/sdc: 15,9GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name     Flags
 2      1049kB  2097kB  1049kB               primary  bios_grub
 3      2097kB  258MB   256MB   fat32        primary  boot, esp
 4      258MB   2274MB  2016MB               primary
 5      2274MB  12,5GB  10,2GB  ext2         primary
 1      12,5GB  15,9GB  3394MB  ntfs         primary  msftdata
sudodus
источник
3
Хорошо, если это /bin/shсинтаксис, все будет хорошо. Но если вы собираетесь использовать функции, специфичные для bash, тогда необходим shebang. Я и Steeldriver обсуждали это где-то. Aaand Videonauth удалил свой комментарий, прежде чем я смог ответить правильно. Ну что ж
Сергей Колодяжный
@SergiyKolodyazhnyy, вы правы. Таким образом, в этом случае шебанг призван сделать сценарий устойчивым в случае добавления функций, в которых синтаксис может отличаться.
Судод
@SergiyKolodyazhnyy Ну, это было просто предложение, поэтому я подумал, что оставлять комментарии там не нужно, и это только добавит беспорядка. Не стесняйтесь ударить меня в чате и указать свое мнение :)
Videonauth
2

Другим способом было бы запустить интерактивный сеанс sudo с помощью sudo -s(не меняет каталог) или sudo -i(изменяет текущий каталог на корневой домашний каталог), а затем ввести свои команды (без sudo)

Людвик
источник