스크립트가 여러 서버에서 출력을 가져올 것으로 예상

스크립트가 여러 서버에서 출력을 가져올 것으로 예상

여러 서버에서 IQN의 출력을 얻으려고 합니다. 다음 오류가 발생합니다.

오류 출력

spawn /usr/bin/ssh VM2 | /usr/bin/cat /etc/iscsi/initiatorname.iscsi
root@VM2's password:
bash: -c: line 0: syntax error near unexpected token `|'
bash: -c: line 0: `| /usr/bin/cat /etc/iscsi/initiatorname.iscsi'

스크립트

#!/bin/bash

HOSTS="VM2 VM3 VM4 VM1"

read -p "Password: " PASSWORD

for HOST in $HOSTS
do
expect -c "
spawn cat /etc/iscsi/initiatorname.iscsi
    expect {
    "*password:*" { send $PASSWORD\r;interact }
    }
    exit
    "
done

내가 뭐 잘못 했어요?

답변1

우선, 나는 당신이 달성하고 싶은 것이 무엇인지 잘 이해하지 못합니다.

제가 이해한 바로는 모든 서버에서 이를 원한다는 것입니다 cat /etc/iscsi/initiatorname.iscsi. 그렇죠?

interact그런데 왜 모든 서버에서 이 작업을 수행 해야 합니까 ?

각 서버와 파일에 로그인하는 첫 번째 문제에 대한 해결 방법을 게시하겠습니다 cat. 솔루션도 추가하고 싶으시면 interact제가 솔루션을 편집해 드릴 수 있습니다 .

expect그래서 먼저 bash.

따라서 프로그램을 실행하는 데 사용되는 bash 스크립트는 다음과 같습니다. 이 스크립트는 비밀번호가 인쇄되거나 표시되지 않도록 비밀번호를 묻는 메시지를 표시합니다(직접 수행하기 쉽지 않음 expect) .

#!/bin/bash 

expect_script="./connect_to_many_hosts_and_cat_files.exp"

[ ! -f $expect_script ] && echo expect_script does not exist && exit 1

echo "Please enter a password:"

read -s password

$expect_script $password

이제 expect스크립트 자체

#!/usr/bin/expect

if {$argc != 1} {
   puts "please run expect script using bash script"
   puts "that prompts for password"
   exit
}

set password [lindex $argv 0]

# replace hosts names with your host names !!!
set hosts "host1 host2"

foreach host [ split $hosts " " ] {

    set number_of_password_prompts($host) 0

    puts "# "
    puts "# ssh $host"
    puts "# "

    spawn ssh $host
        expect {
            # here I put password check, just in case password is wrong
            # look a bit ugly, but better than nothing
            "Password:" {
                if { $number_of_password_prompts($host) == 0 } {
                    incr number_of_password_prompts($host)
                    puts "# "
                    puts "# Authenticating try $number_of_password_prompts($host)"
                    puts "# "
                    send "$password\r"
                    exp_continue
                } else {
                    puts "# "
                    puts "# Password is wrong"
                    puts "# "
                    exit
                }
            }
            # in case on host /bin/sh or /bin/bash
            "$ " {
                puts "# "
                puts "# cat /etc/iscsi/initiatorname.iscsi"
                puts "# "
                send "cat /etc/iscsi/initiatorname.iscsi \r"
                expect "$ "
            }
            # in case on host /bin/csh
            "% " {
                puts "# "
                puts "# cat /etc/iscsi/initiatorname.iscsi"
                puts "# "
                send "cat /etc/iscsi/initiatorname.iscsi \r"
                expect "% "
            }
            send "exit\r"
            expect eof
            close
        }
}

마지막으로 chmod +x두 파일을 보호하세요. 다른 방법으로도 Expect를 실행할 수 있습니다. 또한 의도한 위치를 올바르게 배치했는지 확인하세요. 나로서는 그렇습니다 /usr/bin/expect. 왜냐하면 당신은 다른 사람이 될 수 있기 때문입니다.

중요한 것이 하나 더 있습니다. expect서버의 프롬프트가 중요하기 때문입니다 . 그렇다면 /bin/bash조건을 추가했습니다. $그렇다면 /bin/csh조건을 추가해야 합니다 %.

$PS1귀하의 팁이나 기타 팁이 어떻게 관리되는지 확인하는 것이 매우 중요합니다 ssh. 프롬프트가 다음과 같은 경우 위 스크립트는 작동하지 않습니다.

    user@host:~>

이것이 작동하려면 조건을 추가해야 합니다.expect

            "> " {
                puts "# "
                puts "# cat /etc/iscsi/initiatorname.iscsi"
                puts "# "
                send "cat /etc/iscsi/initiatorname.iscsi \r"
                expect "> "
            }

저는 왜 일이 제대로 되지 않는지 알아내려고 여러 날을 보냈습니다.

답변2

이런 경우에는 ansible을 사용하세요.

yum install ansible -y
vim /etc/ansible/hosts
[servers]
192.168.0.2
192.168.0.3

ssh-keygen

공개 키를 대상 서버에 복사합니다. 그런 다음 서버에 연결해 보십시오.

ansible servers -m ping

존재하다신뢰할 수 있는 문서서버를 지배하는 방법에 대한 정보를 찾을 수 있습니다.

관련 정보