Exécutez une commande qui nécessite sudo après un certain temps

30

Je fais d'habitude

sleep 4h; command

pour exécuter une commande après 4h. Cependant, si cette commande nécessite sudo, cela ne fonctionnera pas.

Est-il possible de donner la sudopermission au moment où j'exécute la sleepcommande?

Guerlando OCs
la source
quelque chose comme ça unix.stackexchange.com/questions/391796/…
MatsK
Dans ce cas particulier, je pense que vous pouvez simplement utiliser le shutdown. avec sudo et les arguments appropriés pour planifier le sommeil à une heure spécifique.
Oarfish
Quelle est la tâche que vous devez faire et pourquoi le sommeil exact de 4 heures?
Thorbjørn Ravn Andersen

Réponses:

46

Utilisez sudopour démarrer un shell racine où vous exécutez les commandes:

sudo bash -c 'sleep 4h; command'

Chaque commande exécutée dans le shell racine s'exécute avec les autorisations root, ce qui sleepne fait pas de mal. Si vous devez exécuter une commande avec des autorisations utilisateur, utilisez sudo -u USERNAME COMMAND, par exemple:

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

Une autre approche consisterait sudo visudoà autoriser l'exécution de la commande sans accès root, voir: Comment autoriser l'exécution sans demander de mot de passe à l'aide de sudo?
Notez que selon la commande, cela peut créer une faille de sécurité.

dessert
la source
21

En supposant que vous ne souhaitiez exécuter le processus qu'une seule fois (pas, par exemple toutes les 4 heures), vous pouvez utiliser atd

  1. Assurez-vous que atd est en cours d'exécution (dans ubuntu c'est /etc/init.d/atd statusou mieux encore systemctl status atd)
  2. Sur un terminal en tant que root, exécutez votre commande comme suit:

    # at now + 4 hours
    warning: commands will be executed using /bin/sh
    at> command
    at> CTRL-D
  3. Si vous voulez l'exécuter toutes les 4 heures, vous pouvez également utiliser cron (en tant que root) avec la configuration suivante dans votre crontab

    0 */4 * * * sh -c $'/path/to/command'
Ama Aje My Fren
la source
2
Oui, atest le bon outil pour ce travail, car il prend également en charge la redirection des E / S, ne bloque pas une fenêtre shell et fonctionne même lorsque l'utilisateur s'est déconnecté ou que la machine a été redémarrée depuis.
Simon Richter
4
@SimonRichter: sudo bash -c 'sleep 4h && command' &mettre sudo en arrière-plan est un moyen plus simple de ne pas bloquer une fenêtre / tabulation de shell. Si vous souhaitez que la sortie s'affiche de manière asynchrone pour rappeler que cela s'est produit, c'est plus facile. Cela ne fonctionne pas lors des redémarrages, mais selon vos nohupparamètres, il peut continuer à fonctionner après avoir quitté / déconnecté d'un shell.
Peter Cordes
4
Notez que atla commande est exécutée dès qu'elle le peut lorsque le système est suspendu à l'heure spécifiée, voir ici sur U&L - selon la ou les commandes à exécuter, cela peut ne pas être ce que vous voulez.
dessert le
2
Juste une suggestion, vous pouvez également utiliser systemctl pour vérifier l'état du service au lieu d'appeler directement ce script init.d. Bien que les deux aient apparemment le même résultat, je pense que la manière moderne d'interagir avec les services systemd devrait être préférée:systemctl status atd
Byte Commander
15

Une façon consiste à exécuter via un shellscript avec des sudoautorisations (et donner le mot de passe, lorsque vous démarrez le shellscript), si le shellscript se trouve dans le répertoire en cours,

sudo ./delayer 4h

delayerpeut être un script avec le contenu

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

Rendez-le exécutable avec

chmod +x delayer

et copiez-le ou déplacez-le dans un répertoire PATHsi vous le souhaitez.


Si vous voulez un shellscript plus flexible, où vous pouvez sélectionner la commande [ligne] pour retarder en entrant le (s) paramètre (s), vous pouvez essayer

#!/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
"$@"

Exemple de démonstration (court délai, 5 s, à des fins de démonstration),

$ ./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
la source
3
Eh bien, si c'est la /bin/shsyntaxe, ça ira. Mais si vous avez l'intention d'utiliser des fonctionnalités spécifiques à bash, alors shebang est nécessaire. Moi et le conducteur d'acier en avons discuté quelque part. Aaand Videonauth a supprimé son commentaire avant que je puisse répondre correctement.
Eh
@SergiyKolodyazhnyy, vous avez raison. Donc, dans ce cas, le shebang est là pour rendre le shellscript robuste en cas de fonctionnalités supplémentaires où la syntaxe peut différer.
sudodus
@SergiyKolodyazhnyy Eh bien, c'était juste une suggestion, donc j'ai pensé que laisser le commentaire là n'était pas nécessaire et ne ferait qu'ajouter à l'encombrement. N'hésitez pas à me contacter dans le chat et à indiquer votre point de vue :)
Videonauth
2

Une autre façon serait de démarrer la session interactive sudo avec sudo -s(ne change pas de répertoire) ou sudo -i(change le répertoire courant en répertoire racine) puis entrez vos commandes (sans sudo)

Ludwik
la source