bash script error stty: Standardeingabe: Unangemessenes ioctl für das Gerät

15

Ich verwende Here-Dokumente in einem Bash-Skript, um die Installation und Einrichtung zu automatisieren, bei denen häufig ein Kennwort erforderlich ist. Ich gebe das Passwort einmal ein und das Skript gibt es an die verschiedenen Befehle weiter. In den meisten Fällen wird dies durch den hier beschriebenen Ansatz erledigt. In einem Fall erhalte ich jedoch den folgenden Fehler:

Enter VNC password: stty: standard input: Inappropriate ioctl for device
Verify password:    
stty: standard input: Inappropriate ioctl for device

Bitte beachten Sie, dass diese Fehlermeldung von x11vnc -storepassword(nicht von sudo) stammt.

Mein Problem ist verbunden mit x11vnc -storepasswdund hier ist mein Code:

sudo x11vnc -storepasswd ~/.vnc/passwd << ENDDOC
password
password
y
ENDDOC

Das geht natürlich (aus dem Fehler) nicht. Ich würde mich über ein funktionierendes Beispiel für die Implementierung sudo x11vnc -storepasswd ~/.vnc/passwdin ein Skript freuen.

Falls es hilft, sehen die Eingabeaufforderungen folgendermaßen aus:

Geben Sie das VNC-Passwort ein:
Passwort bestätigen:
Schreiben Sie ein Passwort an /home/user/.vnc/passwd? [y] / nn

Wird die Verwendung expecteine bessere Lösung sein? Wenn ja, wie würde ich es in diesem Fall verwenden? (Ich habe es noch nie benutzt, expectaber ich habe mir seit dem Posten dieser Frage viele Beispiele angesehen, und ich kann nicht expectalleine arbeiten.)

MountainX für Monica Cellio
quelle

Antworten:

3

x11vncerwartet, dass die Standardeingabe ein Terminal ist, und ändert den Terminalmodus, um zu vermeiden, dass das Kennwort während der Eingabe wiederholt wird. Wenn die Standardeingabe kein Terminal ist, schlagen die sttyAufrufe zum Aus- und Wiedereinschalten des Echos fehl, daher die angezeigte Warnung.

Erwartung ist in der Tat eine Lösung. Versuchen Sie dieses Skript (ungetestet):

#!/usr/bin/expect -f
spawn x11vnc -storepasswd ~/.vnc/passwd
expect "password:" {send "swordfish" "\r"}
expect "password:" {send "swordfish" "\r"}
expect "Write*\?" {send "y\r"}

Wenn möglich, können Sie auch eine andere Authentifizierungsmethode als RFB ( -passwdfileoder ein SSL-Clientzertifikat) verwenden.

Gilles 'SO - hör auf böse zu sein'
quelle
Vielen Dank. Der Fehler kommt jedoch nicht von sudodort x11vnc -storepassword. Ich habe verschiedene expectAnsätze ausprobiert und ich kann es nicht richtig machen. Ein Beispiel expectfür die Eingabe eines Passworts x11vnc -storepasswordwäre sehr dankbar. Ich werde meine Frage aktualisieren, um weitere Verwirrung zu vermeiden.
MountainX für Monica Cellio
@MountainX Richtig, sorry, ich habe die Frage falsch verstanden. Hier ist ein Expect-Skript (völlig ungetestet).
Gilles 'SO- hör auf böse zu sein'
Vielen Dank. Ihr ungetestetes Skript hat mir ein paar zusätzliche Hinweise gegeben, aber letztendlich läuft es auch nicht fehlerfrei. Der Fehler ist einfach Enter VNC password: usage: send [args] stringin der Leitung expect "password:" {send "swordfish" "\r"}. Ich bin mir nicht sicher, wie ich das beheben soll. Expect scheint ein sehr wählerisches Tool zu sein, da ich mich stundenlang mit diesem speziellen Problem herumgetrieben habe, ohne dass es funktioniert hat.
MountainX für Monica Cellio
Der Fehler (obiger Kommentar) kam von send "swordfish" "\r"und wurde von behoben send "swordfish\r". Die Lösung funktioniert jedoch immer noch nicht. In ~ / .vnc / passwd wird kein Passwort geschrieben. Ich weiß immer noch nicht warum. Wie gesagt, ich habe dieses Ergebnis gesehen, obwohl ich alles versucht habe, was mir bisher einfiel.
MountainX für Monica Cellio
Übrigens expectfunktionieren dieselben Befehle, die in Ihrer Lösung verwendet werden, wenn sie manuell eingegeben werden. Sie funktionieren nicht in diesem expectSkript oder einer Variation davon, die ich bisher ausprobiert habe.
MountainX für Monica Cellio
5

Eine andere Möglichkeit, diese Warnmeldungen zu vermeiden, besteht darin, sie x11vncin einem Pseudo-Terminal auszuführen, das mit einem UNIX-Befehl erstellt wurde (siehe Verwenden von Pseudo-Terminals (pty) zur Steuerung interaktiver Programme ). Dies kann mit dem scriptBefehl oder Tools wie pdip("Programmierter Dialog mit interaktiven Programmen") erfolgen.

Die Warnmeldungen unter Mac OS X 10.6.8 für die Nichtbereitstellung eines Pseudoterminals für x11vnc:

# x11vnc 0.9.14
sudo x11vnc -storepasswd ~/.vnc/passwd << ENDDOC
password
password
y
ENDDOC

# Enter VNC password: stty: stdin isn't a terminal
#
# Verify password:    
# stty: stdin isn't a terminal
# Write password to ~/.vnc/passwd?  [y]/n Password written to: ~/.vnc/passwd

Lösungen mit dem scriptBefehl:

# GNU script command
sudo script -q -c 'x11vnc -storepasswd ~/.vnc/passwd' <<ENDDOC /dev/null
password
password
y
ENDDOC

# ... or ...
printf '%s\n' 'password' 'password' 'y' | 
   sudo script -q -c 'x11vnc -storepasswd ~/.vnc/passwd' /dev/null


# FreeBSD script command
sudo script -q /dev/null x11vnc -storepasswd ~/.vnc/passwd <<ENDDOC
password
password
y
ENDDOC
Kalou
quelle
1

Sudo hat eine Option -S, mit der es das Passwort von STDIN lesen kann.

[user@evil ~]$ tail -1 /etc/shadow
tail: cannot open `/etc/shadow' for reading: Permission denied
[user@evil ~]$ echo 'P@ssW3rd!' | sudo -S tail -1 /etc/shadow
nfsnobody:!!:15891::::::

Hier ist ein Beispielskript, um den Prozess zu demonstrieren:

#!/bin/bash

function hr {
    perl -e 'print "-" x 80, "\n";'
}

hr
read -p "Please enter your sudo password: " -s sudopasswd
echo

hr
echo "-sudo run: tail -1 /etc/shadow"
tail -1 /etc/shadow

hr
echo "+sudo run: tail -1 /etc/shadow"
echo "$sudopasswd" | sudo -S tail -1 /etc/shadow

hr
echo "-sudo run: ls -la /root/"
ls -la /root/

hr
echo "+sudo run: ls -la /root/"
echo "$sudopasswd" | sudo -S ls -la /root/

hr

Ihr Skript müsste einfach so etwas tun:

read -p "Please enter your sudo password: " -s sudopasswd
echo "$sudopasswd" | sudo -S x11vnc -storepasswd ~/.vnc/passwd 

Auf diese Weise können Sie sudo-Befehle in Ihrem Skript verwenden, ohne ein Kennwort fest codieren zu müssen.

Alternativ können Sie Ihrem Benutzer oder einer Untergruppe von Benutzern die Möglichkeit hinzufügen, x11vnc mit sudo ohne Kennwort auszuführen. Fügen Sie jedoch eine Zeile wie die folgende hinzu /etc/sudoers:

user    ALL=(root) NOPASSWD: /path/to/x11vnc

Oder erstellen Sie eine vncusersGruppe, fügen Sie dieser Gruppe Benutzer hinzu und fügen Sie Folgendes hinzu zu /etc/sudoers:

%vncusers    ALL=(root) NOPASSWD: /path/to/x11vnc
Tim Kennedy
quelle
Vielen Dank. Der Fehler kommt jedoch nicht von sudodort x11vnc -storepassword.
MountainX für Monica Cellio