1. 程式人生 > >ssh采用expect實現自動輸入密碼登錄、拷貝

ssh采用expect實現自動輸入密碼登錄、拷貝

cep .html tro from 效果 方式 目標 led 交互

1. 引言

最近做了一個項目,需要頻繁與另一臺主機進行文件的傳輸;中間想到了很多方式:FTP、samba、curl等,但是還是感覺scp最好用。

  • SCP使用教程可參閱:http://www.jb51.net/article/70919.htm

但scp也存在著一些問題,每次都需要輸入目標機的密碼,需人為手動幹預,這個就比較煩了,那麽有沒有可以自動進行界面交互的命令呢?

  • 答案當然是:有; expect嘍
  • except使用教程:https://www.cnblogs.com/lixigang/articles/4849527.html

使用shell嵌套使用expect命令工作,很好的達到了文件的批量傳輸,無需人工幹預的效果。

2. 內容詳解

2.1 目標

本博的目的是為了解決項目中出現的問題:scp文件時,需要人為幹預(輸入密碼等),且scp需要輸入目的主機+絕對路徑

而采用本博的腳本,可以實現快速簡單的文件拷貝,而不需要輸入目標主機的ip等,且無需人為幹預輸入目的主機的密碼,實現快速、高效的文件傳輸

2.2 實現框架

  • 1 目標主機的ip地址以變量的形式寫入到腳本中,因此省略了每次輸入目標ip的繁瑣
  • 2 將目標主機的登錄密碼寫入到腳本中,采用expect工具自動抓取密碼,省略了人為的交互界面
  • 3 scp分為pull和push兩種情況,本腳本的處理是:

    • push狀態:即推送文件到目的主機,推送到的位置固定在目標主機的一個目錄下,因此,便可以省略了每次都要寫目標主機和存放的文件位置;命令如下:
      scp <local-file/dir>
    • pull狀態:即從遠程目標主機拉取文件到本機,無需寫目標主機的ip,只要寫上需要拉取的目標主機的文件和本機存放的位置即可,命令如下:
      scp <remote-file/dir> <local-file/dir>

2.3 實現代碼

#==============================================================
#CopyRight: 2018-06-03@jimmy_nie
#E-mail: [email protected]
#Autor  Date        Modify
#Jimmy  2018-06-01  create
#==============================================================
#!/bin/bash

TAR_MAC="[email protected]"     #目標主機的IP地址
TAR_DIR="/mnt/UDISK"            #目標主機存放文件的位置

# 1. Determine the scp is push or pull, if there only 1 argument(push); 2(pull)
if [ $# -eq 1 ];then
    FLAG="PUSH"
elif [ $# -eq 2 ];then
    FLAG="PULL"
else
    echo -e "scpd useage:\n\tscpd local_dir[file] \t\t\t --- push local dir/file to remote $TAR_MAC:$TAR_DIR             \n\tscpd remote_dir[file] local_dir[file] \t --- pull $TAR_MAC file/dir to local [without $TAR_MAC, only remote dir/file]\n"
    exit 1 
fi 

# 2. If push, Determine whether the destinated file existed or not
if [ "$FLAG" == "PUSH" ];then
    if [ -f $1 -o -d $1 ];then
        expect -c "                                     #采用expect工具的命令(註意與shell命令的差異)
            spawn scp -r \"$1\" \"$TAR_MAC:$TAR_DIR\"   #-r為遞歸,將本機的文件/目錄發送到目標機的固定位置
            expect \"*password:\"                       #當遇到以“*password:”結尾的字符串時
            set timeout 100                             #設置超時時間,超過這個時間,scp執行失敗
            send \"123123\r\"                           #將密碼填入到password中,相當於人為輸入密碼
            expect eof                                  #執行結束
        "
    else
        echo -e "$1 does not normal file or directory"
        exit 1
    fi

# 3. If pull, determine whether local dir existed or not
elif [ "$FLAG" == "PULL" ];then
    if [ ! -e $2 -a "$2" == "*/" ];then     #如果本機的目錄不存在,則創建該目錄,再執行拷貝
        mkdir -p \"$2\"
        expect -c "
            spawn scp -r \"$TAR_MAC:$1\" \"$2\"
            expect \"*password:\"
            set timeout 600
            send \"123123\r\"   
            expect eof
        "
    else
        expect -c "
            spawn scp -r \"$TAR_MAC:$1\" \"$2\"
            expect \"*password:\"
            set timeout 600
            send \"123123\r\"   
            expect eof
        "
    fi

fi

#4. Output error info
if [ ! $? -eq 0 ]; then 
    if [ "$FLAG" == "PUSH" ];then
        echo -e "PUSH $1 to $TAR_MAC:$TAR_DIR failed"
    elif [ "$FLAG" == "PULL" ];then
        echo -e "PULL $2 from $TAR_MAC:$1 failed"
    fi
fi

ssh采用expect實現自動輸入密碼登錄、拷貝