1. 程式人生 > 其它 >Linux 自動化執行命令

Linux 自動化執行命令

我們經常需要進行一些自動化,定時執行的指令碼時。
經常會需要我們手動輸入的情況。為了繞過這些互動式的驗證。我選擇使用 sshpassexpect 來解決。

sshpass

sshpass 是一個簡單、輕量級的命令列工具,通過它我們能夠向命令提示符本身提供密碼(非互動式密碼驗證)。

安裝:

yum install sshpass -y

使用:

sshpass -p <password> ssh -o StrictHostKeyChecking=no <username>@<ip> "command"

示例:

# 遠端執行命令
sshpass -p <password> ssh -o StrictHostKeyChecking=no <root>@<ip> "ls -al"
# 遠端連線
sshpass -p <password> ssh -o StrictHostKeyChecking=no <root>@<ip>

expect

expect 是基於 TCL 的相對簡單的一個免費指令碼程式設計工具語言,用來實現自動和互動式任務進行通訊,無需人的手工干預。

安裝:

yum install -y expect

常用用法:

  • send: 用於向程序傳送字串
  • expect: 從程序接收字串
  • spawn: 啟動新的程序
  • interact: 允許使用者互動,把控制權交給控制檯,這個時候就可以手工操作了
  • expect eof: 這個與 spawn 對應表示捕獲終端輸出資訊終止,類似於 if….endif

特別說明下:

  • send 命令接收一個字串引數,並將該引數傳送到程序中去,一般用來發送到 spawn 命令啟動的程序中去。
  • expect 命令和 send 命令正好相反, expect 命令通常是用來等待一個程序的反饋。
  • expect 命令可以接收一個字串引數,也可以接收正則表示式引數。一般用來等待 spawn 命令啟動的程序的反饋。

示例:

使用 expect 來遠端登陸 ssh

#!/usr/bin/expect
# 告訴系統使用那個shell來執行檔案

set timeout 30
# 設定超時時間的秒數, timeout -1 為永不超時

set HOST [lindex $argv 0]
# 將第一個引數賦值給HOST變數

set PASSWORD [lindex $argv 1]
# 將第二個引數賦值給PASSWORD變數

spawn ssh root@$HOST
# 啟動新的程序,該程序使用 root 賬號 ssh 遠端登陸 $HOST 地址

expect {
    "yes/no" {
        send "yes\r";
        exp_continue
    }
    "password:" {
        send "$PASSWORD\r"
    }
}

# 多分支等待ssh程序的反饋
# 如果字串中包含 yes/no 時,執行分支一
# 如果字串中包含 password: 時,執行分支二
# 其中 exp_continue 附加於某個 expect 判斷項之後,可以使該項被匹配後,還能繼續匹配該 expect 判斷語句
# 關於 \r 是因為 expect的字元處理是沒有換行符之類的,所以需要額外加上

expect "*#"
send "ll -a\r"
# 以上兩句是單分支匹配到 # 時執行 ll -a

expect eof
exit
# expect eof和exit是指監測到eof就會執行exit,退出程式。

在 bash 中巢狀使用 expect ,示例中進行 maven 自動打包

#!/usr/bin/env bash

DIR_LIST=("module1" "module2" "module3" "module_build" "module4" "module5")
PASSWORD="password\r"

for dir in ${DIR_LIST[@]}
do
    # echo $dir
    if [ -d "$dir" ]; then
        rm -rf "$dir"
    fi
    GIT_URL="git clone -b dev [email protected]:/gitrepo/xxx/$dir"
    # echo $GIT_URL
    /usr/bin/expect <<-EOF
    set timeout -1
    spawn $GIT_URL
    expect "*password:"
    send $PASSWORD
    expect eof
    EOF
    echo -e "\n"
done

sleep 1

mvn clean install -f module_build/ -Dmaven.test.skip=true