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이러한 경고 메시지를 방지하는 또 다른 옵션은 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

관련 정보