bash脚本错误stty:标准输入:设备的ioctl不适当


16

我在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独自工作。)

Answers:


3

x11vnc希望其标准输入为终端,并且它将更改终端模式以避免在键入时回显密码。当标准输入不是终端时,stty关闭回声和重新打开的调用将失败,因此会显示警告。

期望确实是一个解决方案。尝试以下脚本(未经测试):

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

或者,如果可以,请使用RFB以外的身份验证方法(-passwdfile或SSL客户端证书)。


谢谢。但是,错误不是来自sudo而是来自x11vnc -storepassword。我一直在尝试各种expect方法,但似乎做不到。一个expect用于输入密码的示例x11vnc -storepassword将不胜感激。我将更新我的问题以避免进一步的混乱。
Monica的MountainX

@MountainX对,对不起,我会误解这个问题。这是一个期望脚本(完全未经测试)。
吉尔斯(Gilles)'所以

谢谢。您未经测试的脚本为我提供了其他一些线索,但最终它也不会没有错误地运行。错误很简单Enter VNC password: usage: send [args] string就行了expect "password:" {send "swordfish" "\r"}。我不确定该如何解决。Expect似乎是一个非常挑剔的工具,因为我一直在困扰这个特定问题达数小时之久,但尚无任何工作结果。
Monica的MountainX

错误(以上注释)来自,由send "swordfish" "\r"解决send "swordfish\r"。但是,该解决方案仍然无法正常工作。没有密码写入〜/ .vnc / passwd。我仍然对为什么一无所知。正如我说的,尽管尝试了到目前为止我能想到的一切,但我一直看到这种结果。
Monica的MountainX

顺便说一句,expect手动输入解决方案中使用的相同命令。它们不适用于此expect脚本或到目前为止我尝试过的任何变体。
Monica的MountainX

5

避免这些警告消息的另一种方法是x11vnc在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

1

Sudo有一个选项-S,允许它从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

谢谢。但是,错误不是来自sudo而是来自x11vnc -storepassword
Monica的MountainX
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.