3
votes

Entrez le mot de passe sudo dans le script expect

J'ai un code expect dans le script bash, quelque chose comme ceci

env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
    set timeout -1
    spawn ./another_script.sh
    expect {
        "Input 1" { send -- "$env(input1)\r";exp_continue }
        "Input 2" { send -- "$env(input2)\r";exp_continue }
        eof
    }
EOS

Pendant l'exécution de another_script.sh , je suis invité à entrer le mot de passe sudo, mais je Je ne peux pas car je suis toujours en attente. Que puis-je faire pour que je puisse entrer le mot de passe sudo et que le script continue de fonctionner après cela? Je ne veux pas enregistrer le mot de passe dans le script, puis le transmettre comme prévu, mais je veux pouvoir le saisir.


3 commentaires

Laisser l'utilisateur prendre le contrôle de manière interactive est le but de la fonction Expect interagir .


Je n'ai pas trouvé d'exemple correct / fonctionnel d'utilisation de interagir . J'ai essayé quelque chose comme ce "mot de passe pour" {interact -o "\ r" return; exp_continue} , mais un problème est qu'il est visible ce que je suis en train de taper, et l'autre est qu'après avoir appuyé sur ENTER, rien ne se passe, c'est à dire. le script ne continue pas de fonctionner.


Je voudrais probablement avoir une balise tcl si vous voulez que les gens qui sont expect experts ici. ( expect est une extension du langage TCL, ne fait pas partie de bash; puisque vos problèmes n'ont rien à voir avec la façon dont vous commencez, attendez de bash, et tout à voir avec la façon dont il se comporte après son démarrage , ce n'est pas particulièrement une question bash).


4 Réponses :


0
votes

De man sudo : La politique sudoers met en cache les informations d'identification pendant 15 minutes, sauf si elle est remplacée dans sudoers (5).

Avec cela, appelez sudo -v avant d'appeler expect. Il vérifie les informations d'identification, et si elles ne sont pas mises en cache, il demandera le mot de passe root. De cette façon, vous pouvez les saisir avant expect et les commandes sudo ultérieures n'ont pas besoin de demander à nouveau.


3 commentaires

Le another_script.sh s'exécute pendant quelques heures, donc le délai d'expiration des informations d'identification mises en cache dans cette période.


@adamm Pouvez-vous ajouter les commandes appropriées à / etc / sudoers pour l'accès NOPASSWD ?


Je ne peux pas faire ça.



0
votes

pour ce que vous commentez, je pense que vous l'avez dans cron. Dans ce cas, vous devez exécuter le script en tant que sudo. vous pouvez simplement l'appeler dans le sudo crontab. vous pouvez y accéder en exécutant sudo crontab -e


1 commentaires

L'exécution dans cron est l'endroit où vous ne pouvez absolument pas parler à l'utilisateur et devez plutôt prendre les informations d'identification ailleurs. De toutes les options, la lecture à partir d'un fichier est parmi les meilleures. Ou vous pouvez simplement mettre le script dans le crontab de root et ne pas avoir besoin d'informations d'identification du tout ...



3
votes

La manière standard de gérer un événement comme celui-ci est de rechercher une invite pour le mot de passe sudo, de le fournir, puis de continuer. Mais avec un script de longue durée, vous voudrez mettre en cache le mot de passe dans le script attendu afin de ne pas avoir à revenir plusieurs fois vers l'utilisateur pendant quelques heures. En effet, pour la facilité d'utilisation, vous devez probablement demander le mot de passe à l'avance plutôt que d'attendre que le système sous-jacent en ait besoin.

Heureusement, attendez-vous à inclure le support pour stty, donc c'est une chose facile à ajouter.

env input1=${INPUT1} input2=${INPUT2} expect << "EOS"
    # Prompt for password, cribbed/converted from example on expect(1) manpage
    stty -echo
    send_tty "sudo password: "
    expect_tty -re "(.*)\n"
    send_tty "\n"
    set password $expect_out(1,string)
    stty echo

    # Rest of the script, with clause for sending the password at the right time
    set timeout -1
    spawn ./another_script.sh
    expect {
        "Input 1" { send -- "$env(input1)\r"; exp_continue }
        "Input 2" { send -- "$env(input2)\r"; exp_continue }
        "assword: " { send -- "$password\r"; exp_continue }
        eof
    }
EOS


5 commentaires

Merci pour le commentaire. J'ai essayé votre suggestion, mais j'obtiens cette erreur sudo password: send: spawn id exp0 pas ouvert lors de l'exécution de "send_user" \ n "" Vous avez mentionné que je pouvais surveiller une invite, la fournir puis continuez. Comment puis je faire ça? Je pense que ce serait la réponse à la question initiale.


Cela pourrait être la façon dont vous enveloppez un script expect dans un script bash (que je viens de copier de vous). Je ne sais toujours pas pourquoi les gens qui écrivent attendent des scripts comme ça.


C'est parce que je ne veux pas d'un fichier de plus juste pour le script attendu. J'ai un gros script bash, et j'attends des invites (Entrée 1 et Entrée 2). Expect semblait être la solution pour cela, donc je viens de "incorporer" l'attente à l'intérieur du script bash.


@adamm Je pense que je l'ai résolu en changeant respectivement send_user et expect_user en send_tty et expect_tty . Je pense que stty n'a pas besoin d'être changé.


Ça fonctionne maintenant. Ce n'est pas ce que je cherchais dans la question, mais c'est très utile.



3
votes

La réponse de Donal Fellows est la bonne voie à suivre, mais par souci d'exhaustivité, voici la solution interact que vous avez essayée. La commande à utiliser est

expect {
    "Input 1" { send -- "$env(input1)\r"; exp_continue }
    "Input 2" { send -- "$env(input2)\r"; exp_continue }
    "password for" { stty -echo
                    interact -u tty_spawn_id -o "\r" return
                    stty echo
                    exp_continue }
    eof
}

Le problème que vous avez est que vous exécutez expect avec le script sur stdin, donc interagissez a des problèmes à moins que vous n'utilisiez -u tty_spawn_id pour le faire fonctionner avec / dev / tty et l'utilisateur. Vous devez activer / désactiver l'écho sur ce tty explicitement, car sudo ne l'aura fait que sur le pty entre la commande générée et expect.


0 commentaires