bashスクリプトエラーstty:stdin:デバイスに不適切なioctl

bashスクリプトエラーstty:stdin:デバイスに不適切なioctl

私はbashスクリプトでhere-documentsを使用してパスワードを必要とするいくつかのインストールと設定を自動化しています。パスワードを一度入力すると、スクリプトはそれをさまざまなコマンドに渡します。ほとんどの場合、ここでの文書化アプローチはこの問題をうまく処理します。ただし、場合によっては、次のエラーが発生します。

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

このエラーメッセージは、からのものでx11vnc -storepasswordはなくからのものですsudo

私の問題は以下に関連していますx11vnc -storepasswd。これが私のコードです。

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

明らかに(エラーと判断した場合)これは機能しません。私はsudo x11vnc -storepasswd ~/.vnc/passwdこれをスクリプトで実装する方法の実際の例をしたいと思います。

役に立つなら、ヒントは次のとおりです。

VNCパスワード入力:
パスワード確認:
/home/user/.vnc/passwdにパスワードを書きますか? [y]/nn

使用する方がexpect良いソリューションですか?では、この場合はどのように使用すればよいでしょうか? (これまで使ったことはありませんが、expectこの質問を投稿してから多くの例を見ましたが、expect自分で動作させることはできません。)

答え1

x11vncこれらの警告メッセージを防ぐもう1つのオプションは、UNIXコマンドで生成された疑似端末で実行することです(参照:擬似端末(pty)を使用した対話型プログラムの制御)。これは、(「対話型プログラムを使用した会話プログラミング」)scriptなどのコマンドまたはツールを介して実行できます。pdip

Mac OS X 10.6.8では、疑似端末に関する警告メッセージは使用できません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

次のコマンドを使用して解決しますscript

# 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

答え2

x11vnc標準入力は端末であると予想され、入力時にパスワードがエコーされるのを防ぐために端末モードを変更します。標準入力が端末でない場合、sttyエコーを閉じて再度開く呼び出しが失敗するため、警告が表示されます。

Expectは実際に解決策です。このスクリプトを試してみてください(テストされていません):

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

-passwdfileまたは、可能であれば、RFB(またはSSLクライアント証明書)以外の認証方法を使用してください。

答え3

-SSudoにはSTDINからパスワードを読み取るオプションがあります。

[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::::::

以下は、プロセスを示すサンプルスクリプトです。

#!/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

スクリプトは次の操作を実行できます。

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

これにより、パスワードをハードコードせずにスクリプトでsudoコマンドを使用できます。

あるいは、sudoを使用してx11vncを実行できるように、ユーザーまたはユーザーのサブセットを追加することもできます。パスワードは必要ありませんが、次の行を追加できます/etc/sudoers

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

または、vncusersグループを作成してグループにユーザーを追加したら、次を追加します/etc/sudoers

%vncusers    ALL=(root) NOPASSWD: /path/to/x11vnc

関連情報