Shell 자동 대화 스 크 립 트 - 비밀번호 자동 추가 등

8742 단어 linux
최근 에 암호 없 이 호스트 에 로그 인 하려 면 상호작용 스 크 립 트 를 사용 하여 스 크 립 트 의 상호작용 방법 을 정리 해 야 합 니 다.
1. 가장 간단 한 상호작용: echo + 파이프 - 이전 명령 의 출력 은 다음 명령 의 표준 으로 stdin 을 입력 합 니 다.
예 를 들 어 자동 파 티 션:
echo -e "n




w" | fdisk /dev/sdb ( echo -e "n
p
1


w" | fdisk /dev/sdb)

2 、 내 연 입력 재 설정: Comand <
예 를 들 어 위의 자동 파 티 션 은 쓸 수 있 습 니 다.
fdisk /dev/vdb <n
>p
>1
>
>
>w
>EOF

3. ssh 처럼 자동 으로 비밀 번 호 를 입력 해 야 하 는 상기 두 가지 방식 으로 해결 할 수 없 으 면 오늘 의 주인공 - expect 를 사용 해 야 합 니 다.
expect 는 TCL 언어 를 바탕 으로 상호작용 스 크 립 트 디자인 을 하 는 것 으로 단독으로 쓸 수도 있 고 셸 에 통합 할 수도 있 습 니 다. 기본 문법:
#!/usr/bin/expect
set        
spawn        
expect        ,  spawn     
send/send_user   expect  ,  expect      ,       spawn  ,send_user   shell echo,         。

물론 expect 도 셸 에 통합 할 수 있 습 니 다. 통합 방식 은 다음 과 같 습 니 다.
#!/bin/bash
expect -c "
spawn ssh compute1 lsblk
expect {
"(yes/no)" {send yes
;exp_continue} } expect eof"
#    :expect       send           ,  shell            ,    yes/no      ,  yes
, “yes\

이 안에 제 가 쓴 스 크 립 트 를 넣 습 니 다. 모든 기 계 를 모 으 려 면 ssh 암호 없 는 상호 방문 을 해 야 합 니 다. 여기 서 재 미 있 는 현상 을 발 견 했 습 니 다. expect 스 크 립 트 에서\r 와 바 꿀 수 있 습 니 다. 이것 은 셸 에서 안 됩 니 다. Liux 에서\r 를 사용 하지 않 고 Enter + 줄 바 꾸 기 만 표시 하기 때 문 입 니 다.
#!/bin/bash
#1、 check if host.txt exsits
if [ ! -e ./hosts.txt ];then
        echo "Usage: need host.txt in the same directory,format 'IP HOSTNAME' one line"
else  
#    DNS hosts  
        cat ./hosts >>/etc/hosts  

#2、  ssh  
expect -c "
 spawn ssh-keygen
 expect {
     "*exists*" {send n\r}                #          ,     expect eof  
     "file" {send \r ; exp_continue}        #       ,         ,send       exp_continue,       expect   eof  ,         
     "passphrase" {send \r ; exp_continue}
     "again" {send \r}
 }
 expect eof"

#3、           (grep        hosts  !!)
for host in `cat /etc/hosts|grep test|awk '{print $2}'|sort -nr|uniq`    #    uniq              ,      sort  
do
  expect -c "
  spawn ssh-copy-id -f $host
  expect {
       \"yes/no\" {send yes\r;expect "*assword" {send 123\r}}  #          
       \"password\" {send 123\r}
  }
  expect eof"
done

#4、                     ,                      ,     2.3      copy.sh  scp   root ,        
for host in `cat /etc/hosts|grep test|awk '{print $2}'|sort -nr|uniq`
do
  expect -c "
  spawn scp copy.sh $host:/root/
  expect {
       \"yes/no\" {send yes\r ; expect "*assword" {send 123\r}}
       \"password\" {send 123\r}
  }
  
  spawn ssh $host ./copy.sh  #     spawn  ,    expect -c        eof      ,        expect -c   。  eof   spawn,    ssh        ,      exit
                             #      , ssh      ,       spawn  ,           ssh spawn     ,          ,       spawn ssh $host expect "~\]\#" {send ./copy.sh}
  expect eof"
done

echo "Success!!!"

fi

위의 스 크 립 트 에 명 시 된 문제 외 에 다음 과 같은 몇 가지 문제 가 있 습 니 다.
1. 직렬 병렬 문제.expect 판단 에 병렬 로 놓 여 있 습 니 다. 셸 의 case 와 일치 합 니 다. 어떤 키워드 에 맞 게 다음 {send} 을 실행 합 니까?순서 에 놓 인 두 expect 는 직렬 입 니 다.직렬 이면 일부 장면 앞에서 잘못 보고 하고 종료 하면 뒤의 동작 을 실행 하지 않 습 니 다. 예 를 들 어 sudo 에서 앞 에 sudo 가 있 으 면 다시 sudo 를 할 때 비밀 번 호 를 입력 하지 않 아 도 됩 니 다 (5 분 이내). 그러면 첫 번 째 expect 와 일치 하면 비밀 번 호 를 누 르 면 잘못 판단 하여 미리 뛰 어 내 립 니 다.
2. 매개 변수 문제: $argc 통 셸 의 $\#,    매개 변수 용 [lindex $argv n] 은 0 은 첫 번 째 를 나타 내 고 n 은 n + 1 개의 인 자 를 나타 낸다. 예 를 들 어 set user [lindex $argv [expr] $argc - 1]], user 를 제 (총 매개 변수 수) 매개 변수 로 정의 하고 계산 기 는 expr 산식 을 사용 해 야 합 니 다.
다음은 일괄 작업 스 크 립 트 입 니 다:
6. 인 스 턴 스: 다음 스 크 립 트 는 단일 서버 scp 작업 을 수행 합 니 다.
 1: #!/usr/bin/expect
 2: 
 3: set timeout 10
 4: set host [lindex $argv 0]
 5: set username [lindex $argv 1]
 6: set password [lindex $argv 2]
 7: set src_file [lindex $argv 3]
 8: set dest_file [lindex $argv 4]
 9: 
 10: spawn scp $src_file $username@$host:$dest_file
 11: expect {
 12:     "(yes/no)?"
 13:         {
 14:             send "yes
"
 15:             expect "*assword:" { send "$password
"
}
 16:         }
 17:     "*assword:"
 18:         {
 19:             send "$password
"
 20:         }
 21:     }
 22: expect "100%"
 23: expect eof

코드 가 처음 시 작 된 첫 줄 에 주의 하 십시오. expect 의 경 로 를 지정 하 였 습 니 다. 셸 스 크 립 트 와 같 습 니 다. 이 문장 은 프로그램 이 실 행 될 때 어디로 가서 해당 하 는 시작 프로그램 을 찾 는 지 지정 합 니 다.코드 는 처음에 timeout 시간 을 10 초 로 설정 하 였 으 며, scp 작업 을 수행 할 때 코드 에 지정 한 이상 이 없 으 면 10 초 를 기다 리 면 이 스 크 립 트 의 실행 이 자동 으로 종 료 됩 니 다.
spawn 은 로 컬 터미널 에서 실 행 된 문 구 를 대표 합 니 다. 이 문 구 를 실행 하기 시작 한 후에 expect 는 터미널 의 출력 정 보 를 캡 처 한 다음 에 해당 하 는 동작 을 합 니 다.expect 코드 에서 캡 처 한 (yes/no) 내용 은 대상 호스트 에 처음 접근 할 때 키 를 저장 하 는 데 사 용 됩 니 다.이 한 마디 로 scp 의 임 무 는 중단 되 는 상황 을 줄 였 다.코드 끝 에 있 는 expect eof 는 spawn 과 대응 하여 터미널 출력 정 보 를 캡 처 하 는 종 료 를 표시 합 니 다.
 
이 expect 코드 가 있 으 면 원 격 호스트 에 대한 scp 작업 만 수행 할 수 있 습 니 다.대량 scp 작업 이 필요 하 다 면, 이 expect 스 크 립 트 를 호출 하기 위해 셸 스 크 립 트 를 하나 더 써 야 합 니 다.
1: #!/bin/sh
 2: 
 3: list_file=$1
 4: src_file=$2
 5: dest_file=$3
 6: 
 7: cat $list_file | while read line
 8: do
 9:     host_ip=`echo $line | awk '{print $1}'`
 10:     username=`echo $line | awk '{print $2}'`
 11:     password=`echo $line | awk '{print $3}'`
 12:     echo "$host_ip"
 13:     ./expect_scp $host_ip $username $password $src_file $dest_file
 15: done

간단 한 코드 입 니 다. 목록 파일 의 위치, 로 컬 소스 파일 경로, 원 격 호스트 대상 파일 경 로 를 지정 합 니 다.설명 할 것 은 목록 파일 이 원 격 호스트 ip, 사용자 이름, 비밀 번 호 를 지정 하 였 습 니 다. 이 정 보 는 다음 과 같은 형식 으로 작성 해 야 합 니 다.
IP username password
중간 에 빈 칸 이나 tab 키 로 구분 되 며, 여러 호스트 의 정 보 는 여러 줄 의 내용 을 써 야 합 니 다.
이렇게 해서 원 격 호스트 두 대의 정 보 를 지정 했다.원 격 호스트 암호 에 '$', '\#' 와 같은 특수 문자 가 있 으 면 목록 파일 을 작성 할 때 이 특수 문자 앞 에 전의 문 자 를 추가 해 야 합 니 다. 그렇지 않 으 면 expect 가 실행 할 때 잘못된 암 호 를 입력 할 수 있 습 니 다.
이 셸 스 크 립 트 에 대해 batch 로 저장 합 니 다.scp. sh 파일, 방금 저 장 된 expectscp 파일 과 목록 파일 (hosts. list 파일 로 정의 합 니 다) 을 같은 디 렉 터 리 에 두 고 실행 할 때 다음 과 같은 방식 으로 명령 을 입력 하면 됩 니 다.
./batch_scp.sh ./hosts.list/root/src_file/root/destfile
참고 문헌:https://blog.csdn.net/nero_g/article/details/53945654

좋은 웹페이지 즐겨찾기