2009-08-19 7 views
2

expect 스크립트를 사용하여 ssh 로그인을 자동화하는 Bash 스크립트를 만들었습니다.이 스크립트는 여러 서버에 연결하고 일부 명령을 실행합니다. bash 스크립트는 로그인 자격 증명을 입력하라는 프롬프트를 한 번 표시합니다.Bash로부터 호출 된 Expect 스크립트의 종료 상태 코드

다음 서버에 대한 스크립트 검사를 피하기 위해 첫 번째 서버에 대한 로그인이 실패하면 스크립트가 종료되는 기능을 통합하여 사용자 계정이 잠기는 결과를 가져오고 싶습니다. 계정 잠금은 3 회 연속 로그인 실패로 발생하고 스크립트가 연결하려고 시도하는 서버 수가 3을 초과합니다.

이것은 expect 스크립트를 호출하는 bash 스크립트의 스 니펫입니다.

countu=0 
for servername in $(cat $linux_host_list) 
do 
./script.expect $LUSERNAME $LPASS $servername Linux >> linux_log_file.txt & < /dev/null 
let countl=countl+1 
done 

여기가 (script.expect가) 내가 로그인이 잘못된 실패하면 bash는 명령이 0이 아닌 값을 반환한다고 가정 bash는 명령 출력 ($?)을 잡아 시도

#!/usr/bin/expect -f 
set timeout 30 
set username [lindex $argv 0] 
set SPASS [lindex $argv 1] 
set servername [lindex $argv 2] 
set case [lindex $argv 3] 
set prompt "(%|#|\\$|%\]) $" 
switch $case { 
    Linux { 
     log_user 0 
     spawn ssh -o StrictHostKeyChecking=no [email protected]$servername 
     expect { 
      "assword:" { 
       send "$SPASS\r" 
       expect -re "$prompt" 
      } 
      expect -re "$prompt" 
     } 
     send "sudo su -\r" 
     expect { 
      "assword:" { send "$SPASS\r" } 
     } 
     expect -re "$prompt" 
     log_user 1 
     send "opcagt -status ; opctemplate -l ; cat watch.cf 2> /dev/null\r" 
     expect -re "$prompt" 
     log_user 0 
     send "exit\r" 
     expect -re "$prompt" 
     log_user 1 
    } 

스 니펫 기대 스크립트입니다 암호는 expect 스크립트에 있지만 작동하지 않습니다. 제안 사항을 보내 주시면 감사하겠습니다.

답변

1

Fabric을 진지하게 고려해야합니다.

+3

솔직히, 나는 기대 이상으로 이동하는 것을 주저합니다. Expect는 수년 동안 자동화 될 것으로 기대하지 않는 시스템 작업을 자동화하는 최고의 도구 중 하나였습니다. 다른 도구가 실제로 비교할 수없는 여러 가지 일을합니다 (예 : tty/사용자를 거의 완벽하게 시뮬레이트하는 기능). 그것은 Fabric이 좋지 않다는 것을 말하지 않습니다. 나는 그것에 대해 아무것도 모릅니다 ... 단지 Expect가 채울 큰 신발이 있습니다. – RHSeeger

+1

나는이 작업을 위해서 Fabric이 만들어 졌기 때문에 이것을 제안했다. 해가되지 않습니다! – iElectric

+0

원단이 멋지게 보입니다. 공유해 주셔서 감사합니다. –

0

내가 이렇게 내가 정확한 단계를 쓸 수 또는 스크립트 내가 마음에 가지고 무엇을 증명하기 위해, 스크립트 및 모든으로 많은 아닙니다 - 친절

그럼 실례, 그 떠들썩한 파티가 종료 상태로 불리는 일을 제공 읽기

종료 상태 당신은 입력하여 종료 상태를 점검 한 후 명령을 실행하고 이것을 볼 수 거짓

에 대한 진정한 0의 상태와 1 또는 다른 것입니다 "에코 $을?"

내가 제안하면 하나 개의 서버로 ssh를 시도하고 인증이 실패 할 경우, 0

이외의 여기 경우 - 당시 다른 루프를 얻기를 0 상태를 점검 종료 상태가되어야한다입니다 스크립트의 실행 및 적절한 오류 메시지가 예상 스크립트에서 오류 검사에 대한

+0

당신이 내 질문을 읽었을 때, 나는 이미 그것을 시도했지만 ($?) 그것이 효과가 없다고 말했다. – Sharjeel

2

와 완전히 스크립트를 종료하기 위해 다른 값을, 당신이 할 일은이 같은 것입니다 http://systeminetwork.com/article/handle-errors-expect-scripts

에서 괜찮은 예를있다 :

proc do_exit {msg} { 
    puts stderr $msg 
    exit 1 
} 

switch -exact -- $case { 
    Linux { 
     spawn ssh ... 
     expect { 
      -re {assword: $} { 
       send -- "$SPASS\r" 
       exp_continue 
       # remain in this expect block and look for the next matching pattern 
      } 
      "some message about incorrect password" { 
       do_exit "incorrect password" 
      } 
      timeout {do_exit "timed out waiting for prompt"} 
      default {do_exit "something else happened"} 
      -re $prompt 
     } 
     # ... rest of your script 
    } 
} 

"opcagt ..."명령 시리즈의 종료 상태에 대해 알 필요가 없다고 가정합니다 (단지 watch.cf 파일의 내용을보고 싶을뿐입니다). 당신이 치료를 할 경우, 당신은 당신에게 쉘을 얻을해야합니다 :

send -- "opcagt -status 2>&1 || echo "non-zero return from opcagt: $?" 
expect { 
    "non-zero return" { handle error and exit? } 
    -re $prompt 
} 
# ... continue 
0

을 당신은 배경 (&)에 기대 스크립트를 실행하고, 당신은 첫 번째의 결과를 가질 수 있도록 계속하기 전에.

첫 번째 암호가 실패 할 경우 예상 스크립트가 작성된 방식으로 두 번째 암호 프롬프트에서 30 초의 시간 초과가 발생합니다. 대신 expect 대안을 사용하여 다른 assword 프롬프트가 표시되는지 확인하고 즉시 종료 할 수 있습니다.

그런 다음 쉘 스크립트를 변경하여 expect 호출을 백그라운드에 넣지 말고 대신 출력을 $?으로 캡처하여 테스트하십시오.

1

섹션은 :

expect { 
     "assword:" { 
      send "$SPASS\r" 
      expect -re "$prompt" 
     } 
     expect -re "$prompt" 
    } 

은 나에게 매우 의심스러운. 특히, 나는 물건이 혼란스럽게되기를 정말로 기대할 것이다. 더 관용적 인 글쓰기 방법은 다음과 같습니다 :

expect { 
     "assword:" { 
      send "$SPASS\r" 
      exp_continue 
     } 
     -re "$prompt" 
    }