2009-10-08 7 views
17

을 사용하여 TELNET 세션에 로그인하는 것을 자동화해야하는데,이 필요하지만 같은 사용자 이름에 대해 여러 암호를 처리해야합니다.'expect'안에 조건문 사용하기

  1. 오픈 TELNET 세션의 IP
  2. 보내기 사용자 이름
  3. 에게 보내기 비밀번호를
  4. 잘못된 암호 :

    여기에 내가 만들 필요가 흐름인가? 그것은 가치가 무엇인지를 들어 ...

  5. 가 성공적으로 로그인 한 했어야
  6. 이 시점에서 다음 다른 암호를 다시

을 동일한 사용자 이름 보내기, 여기에 내가 지금까지있어 무엇 :

#!/usr/bin/expect 
spawn telnet 192.168.40.100 
expect "login:" 
send "spongebob\r" 
expect "password:" 
send "squarepants\r" 
expect "login incorrect" { 
    expect "login:" 
    send "spongebob\r" 
    expect "password:" 
    send "rhombuspants\r" 
} 
expect "prompt\>" { 
    send_user "success!\r" 
} 
send "blah...blah...blah\r" 

말할 필요도없이 이것이 작동하지 않으며 매우 아름답게 보이지 않습니다. Google 으로 모험에서는 어두운 예술의 무언가 인 것을 보인다. 이 문제에 도움을 주신 모든 분들께 미리 감사드립니다!

+0

내 대답에 대한 정보를 추가했습니다. – tvanfosson

답변

31

프로그래머를위한 모든 기대를위한 Exploring Expect 책을 꼭 기억해야합니다. (테스트되지 않은)

proc login {user pass} { 
    expect "login:" 
    send "$user\r" 
    expect "password:" 
    send "$pass\r" 
} 

set username spongebob 
set passwords {squarepants rhombuspants} 
set index 0 

spawn telnet 192.168.40.100 
login $username [lindex $passwords $index] 
expect { 
    "login incorrect" { 
     send_user "failed with $username:[lindex $passwords $index]\n" 
     incr index 
     if {$index == [llength $passwords]} { 
      error "ran out of possible passwords" 
     } 
     login $username [lindex $passwords $index] 
     exp_continue 
    } 
    "prompt>" 
} 
send_user "success!\n" 
# ... 

exp_continue 다시 기대 블록의 시작 부분에 루프 - 그것은 "다시"문처럼 :

난 당신의 코드를 다시 작성했습니다.

send_user\n로 끝나는 참고하지 \r

당신은 당신의 프롬프트에 > 문자를 이스케이프 할 필요가 없습니다 : 그것은 Tcl의 특별한 아니다.

-1

사용자 ID와 암호를 알고있는 경우 어떤 시스템과 정렬 된 사용자 ID/암호 쌍이 있는지 알아야합니다. 어떤 사용자 ID/암호 쌍이 어떤 시스템과 연결되어 있는지 그 정보를 추출하고 올바른 정보를 사용하는 맵을 유지하는 것이 더 나을 것이라고 생각합니다.

내 충고가 마음에 들지 않으므로 wikipedia page을보고 성공하면 0을, 예상 시간을 초과하면 1을 반환하는 절차를 구현하는 것이 좋습니다. 이렇게하면 제공된 암호가 실패했을 때 즉, 예상 시간이 초과 된 경우를 감지하고 다시 시도 할 수 있습니다. 이것이 도움이된다면, 편집 한 downvote를 제거 할 수 있습니다.

회상시 암호를 변경하면 실패한 로그인을 감지하기 때문에지도와 함께이 작업을 수행하는 것이 좋습니다.

+0

downvote 죄송합니다.나는 긴 호출을하고 있었고 나는 이유를 설명하기 위해 게시물을 타이핑하지 않고도 아직 답을 얻지 못했다는 것을 보여주는 빠른 방법을 원했다. 어쨌든 특정 장치에서 사용되는 암호를 문서화 할 수있는 확실한 방법이있는 경우 조건부 방법을 사용하지 않을 것입니다. 그것은 나의 통제 밖에서 펌웨어 수정을 가로 질러 바뀔 수있다. 그래서 내가 할 수있는 누구나는 시험해 볼 준비가되어있는 암호의 목록을 가지고있다. 나는 내가해야 할 일을 이해한다. - 조건문을 사용하고 대답에 따라 행동한다 - 나는 그 방법을 모른다. :) – shuckster

+0

내가 편집 한 투표를 지금 제거 할 수 있습니다. 추가 정보가 도움이되거나 최소한 게시물이 도움이되지 않는 경우입니다. 답변을 수락하지 않는 한 사람들은 답변을 계속 추가 할 것입니다. 그러나 암호를 추적하는 것이 왜 어려운지에 대한 정보로 질문을 업데이트 할 수는 있습니다. – tvanfosson

10

약간의 강타로 해결책을 찾았습니다. expect가 TCL 구문을 사용하여 내가 익숙하지 않다는 것을 알게되었습니다 :

#!/usr/bin/expect 
set pass(0) "squarepants" 
set pass(1) "rhombuspants" 
set pass(2) "trapezoidpants" 
set count 0 
set prompt "> " 
spawn telnet 192.168.40.100 
expect { 
    "$prompt" { 
    send_user "successfully logged in!\r" 
    } 
    "password:" { 
    send "$pass($count)\r" 
    exp_continue 
    } 
    "login incorrect" { 
    incr count 
    exp_continue 
    } 
    "username:" { 
    send "spongebob\r" 
    exp_continue 
    } 
} 
send "command1\r" 
expect "$prompt" 
send "command2\r" 
expect "$prompt" 
send "exit\r" 
expect eof 
exit 

다른 사람들에게 유용하게 사용되기를 바랍니다.

+1

나는 비슷한 해결책을 SSH에 사용했지만 패스워드 파일 '~/.ssh/ssh-passwords'에서 패스워드를 읽었다. 호스트 이름과 사용자 이름은 '~/.ssh/config'파일에서 읽습니다. 그래서 실행 중입니다 : '[cssh] (https://github.com/DavidGamba/bin/blob/master/cssh) server1'은 [email protected]으로 확장됩니다. – DavidG

+0

저는 기대에 새로운입니다. 기대 {case1 "{...}"case2 "{...}"case3 "{...}}, C++과 같은 switch case 문입니까? 감사합니다 –

+0

@ B.Mr.W. 그렇습니다.'''{}'''외부에서 사용하면 기본적으로 개별적인''if if'' 대신 – eulerworks