30個(gè)Linux Shell腳本經(jīng)典案例(下)

1、從FTP服務(wù)器下載文件

#!/bin/bash
if [ $# -ne 1 ]; then
    echo "Usage: $0 filename"
fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v << EOF   # -n 自動(dòng)登錄
open 192.168.1.10  # ftp服務(wù)器
user admin password
binary   # 設(shè)置ftp傳輸模式為二進(jìn)制瓜饥,避免MD5值不同或.tar.gz壓縮包格式錯(cuò)誤
cd $dir
get "$file"
EOF

2、連續(xù)輸入5個(gè)100以內(nèi)的數(shù)字浴骂,統(tǒng)計(jì)和乓土、最小和最大

#!/bin/bash
COUNT=1
SUM=0
while [ $COUNT -le 5 ]; do
    read -p "請輸入1-10個(gè)整數(shù):" INT
    if [[ ! $INT =~ ^[0-9]+$ ]]; then
        echo "輸入必須是整數(shù)!"
        exit 1
    elif [[ $INT -gt 100 ]]; then
        echo "輸入必須是100以內(nèi)溯警!"
        exit 1
    fi
    if [ $COUNT -eq 1 ]; then
        MIN=${INT}
        MAX=${INT}
    fi
    SUM=$(($SUM+$INT))
    [ $INT -lt $MIN  ] && MIN=$INT
    [ $INT -gt $MAX ] && MAX=$INT
    let COUNT++
done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"


# bash 100_sum_min_max.sh
請輸入1-10個(gè)整數(shù):6
請輸入1-10個(gè)整數(shù):99
請輸入1-10個(gè)整數(shù):77
請輸入1-10個(gè)整數(shù):4
請輸入1-10個(gè)整數(shù):55
SUM: 241
MIN: 4
MAX: 99

3趣苏、將結(jié)果分別賦值給變量

應(yīng)用場景:希望將執(zhí)行結(jié)果或者位置參數(shù)賦值給變量,以便后續(xù)使用梯轻。

方法1:
for i in {4..6};do eval a$i=$i;done
echo $a4 $a5 $a6

方法2:將位置參數(shù)192.168.1.1{1,2}拆分為到每個(gè)變量
num=0
for i in $(eval echo $*);do   #eval將{1,2}分解為1 2
   let num+=1
   eval node${num}="$i"
done
echo $node1 $node2 $node3

# bash a.sh 192.168.1.1{1,2}
192.168.1.11 192.168.1.12

方法3:
arr=(4 5 6)
INDEX1=$(echo ${arr[0]})
INDEX2=$(echo ${arr[1]})
INDEX3=$(echo ${arr[2]})

4食磕、批量修改文件名

示例:
# touch article_{1..3}.html
# ls
article_1.html  article_2.html  article_3.html

目的:把a(bǔ)rticle改為bbs

方法1:
for file in $(ls *html); do
    mv $file bbs_${file#*_}
    # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs\1/')
    # mv $file $(echo $file |echo bbs_$(cut -d_ -f2)
done

方法2:
for file in $(find . -maxdepth 1 -name "*html"); do
     mv $file bbs_${file#*_}
done

方法3:
# rename article bbs *.html

5、統(tǒng)計(jì)當(dāng)前目錄中以.html結(jié)尾的文件總大

方法1:
# find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}'

方法2:
for size in $(ls -l *.html |awk '{print $5}'); do
    sum=$(($sum+$size))
done
echo $sum

6喳挑、掃描主機(jī)端口狀態(tài)

#!/bin/bash
HOST=$1
PORT="22 25 80 8080"
for PORT in $PORT; do
    if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then
        echo "$PORT open"
    else
        echo "$PORT close"
    fi
done

7彬伦、Expect實(shí)現(xiàn)SSH免交互執(zhí)行命令

Expect是一個(gè)自動(dòng)交互式應(yīng)用程序的工具,如telnet伊诵,ftp单绑,passwd等。
需先安裝expect軟件包曹宴。

方法1:EOF標(biāo)準(zhǔn)輸出作為expect標(biāo)準(zhǔn)輸入
#!/bin/bash
USER=root
PASS=123.com
IP=192.168.1.120
expect << EOF
set timeout 30
spawn ssh $USER@$IP   
expect {
    "(yes/no)" {send "yes\r"; exp_continue}
    "password:" {send "$PASS\r"}
}
expect "$USER@*"  {send "$1\r"}
expect "$USER@*"  {send "exit\r"}
expect eof
EOF

方法2:
#!/bin/bash
USER=root
PASS=123.com
IP=192.168.1.120
expect -c "
    spawn ssh $USER@$IP
    expect {
        \"(yes/no)\" {send \"yes\r\"; exp_continue}
        \"password:\" {send \"$PASS\r\"; exp_continue}
        \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}
    }"

方法3:將expect腳本獨(dú)立出來
登錄腳本:
# cat login.exp
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]
set cmd [lindex $argv 3]
if { $argc != 4 } {
puts "Usage: expect login.exp ip user passwd"
exit 1
}
set timeout 30
spawn ssh $user@$ip
expect {
    "(yes/no)" {send "yes\r"; exp_continue}
    "password:" {send "$passwd\r"}
}
expect "$user@*"  {send "$cmd\r"}
expect "$user@*"  {send "exit\r"}
expect eof

執(zhí)行命令腳本:寫個(gè)循環(huán)可以批量操作多臺(tái)服務(wù)器
#!/bin/bash
HOST_INFO=user_info.txt
for ip in $(awk '{print $1}' $HOST_INFO)
do
    user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)
    pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)
    expect login.exp $ip $user $pass $1
done

Linux主機(jī)SSH連接信息:
# cat user_info.txt
192.168.1.120 root 123456

8搂橙、批量修改服務(wù)器用戶密碼

Linux主機(jī)SSH連接信息:舊密碼
# cat old_pass.txt 
192.168.18.217  root    123456     22
192.168.18.218  root    123456     22

內(nèi)容格式:IP User Password Port
SSH遠(yuǎn)程修改密碼腳本:新密碼隨機(jī)生成
#!/bin/bash
OLD_INFO=old_pass.txt
NEW_INFO=new_pass.txt
for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do
    USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)
    PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)
    PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)
    NEW_PASS=$(mkpasswd -l 8)  # 隨機(jī)密碼
    echo "$IP   $USER   $NEW_PASS   $PORT" >> $NEW_INFO
    expect -c "
    spawn ssh -p$PORT $USER@$IP
    set timeout 2
    expect {
        \"(yes/no)\" {send \"yes\r\";exp_continue}
        \"password:\" {send \"$PASS\r\";exp_continue}
        \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit\r\";exp_continue}
    }"
done


生成新密碼文件:
# cat new_pass.txt 
192.168.18.217  root    n8wX3mU%      22
192.168.18.218  root    c87;ZnnL      22

9、打印乘法口訣

方法1:
# awk 'BEGIN{for(n=1;n<=9;n++){for(i=1;i<=n;i++){printf i"x"n"="i*n" "} print""}}'

方法2:
for ((i=1;i<=9;i++)); do
   for ((j=1;j<=i;j++)); do
     result=$(($i*$j))
     echo -n "$j*$i=$result "
   done
   echo
done

10浙炼、getopts工具完善腳本命令行參數(shù)

getopts是一個(gè)解析腳本選項(xiàng)參數(shù)的工具份氧。
命令格式:getopts optstring name [arg]
初次使用你要注意這幾點(diǎn):

  • 腳本位置參數(shù)會(huì)與optstring中的單個(gè)字母逐個(gè)匹配,如果匹配到就賦值給name弯屈,否則賦值name為問號蜗帜;
  • optstring中單個(gè)字母是一個(gè)選項(xiàng),如果字母后面加冒號资厉,表示該選項(xiàng)后面帶參數(shù)厅缺,參數(shù)值并會(huì)賦值給OPTARG變量;
  • optstring中第一個(gè)是冒號宴偿,表示屏蔽系統(tǒng)錯(cuò)誤(test.sh: illegal option -- h)湘捎;
  • 允許把選項(xiàng)放一起,例如-ab
    下面寫一個(gè)打印文件指定行的簡單例子窄刘,引導(dǎo)你思路:
#!/bin/bash
while getopts :f:n: option; do
    case $option in
        f)
            FILE=$OPTARG
      [ ! -f $FILE ] && echo "$FILE File not exist!" && exit
            ;;
        n)
            sed -n "${OPTARG}p" $FILE
            ;;
        ?)
            echo "Usage: $0 -f <file_path> -n <line_number>"
            echo "-f, --file           specified file"
            echo "-n, --line-number    print specified line"
            exit 1
        ;;
    esac
done
image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窥妇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娩践,更是在濱河造成了極大的恐慌活翩,老刑警劉巖烹骨,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異材泄,居然都是意外死亡沮焕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門拉宗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峦树,“玉大人,你說我怎么就攤上這事旦事】” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵族檬,是天一觀的道長歪赢。 經(jīng)常有香客問我,道長单料,這世上最難降的妖魔是什么埋凯? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮扫尖,結(jié)果婚禮上白对,老公的妹妹穿的比我還像新娘。我一直安慰自己换怖,他們只是感情好甩恼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沉颂,像睡著了一般条摸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铸屉,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天钉蒲,我揣著相機(jī)與錄音,去河邊找鬼彻坛。 笑死顷啼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昌屉。 我是一名探鬼主播钙蒙,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼间驮!你這毒婦竟也來了躬厌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤竞帽,失蹤者是張志新(化名)和其女友劉穎烤咧,沒想到半個(gè)月后偏陪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煮嫌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抱虐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昌阿。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖恳邀,靈堂內(nèi)的尸體忽然破棺而出懦冰,到底是詐尸還是另有隱情,我是刑警寧澤谣沸,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布刷钢,位于F島的核電站,受9級特大地震影響乳附,放射性物質(zhì)發(fā)生泄漏内地。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一赋除、第九天 我趴在偏房一處隱蔽的房頂上張望阱缓。 院中可真熱鬧,春花似錦举农、人聲如沸荆针。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽航背。三九已至,卻和暖如春棱貌,著一層夾襖步出監(jiān)牢的瞬間玖媚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工键畴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留最盅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓起惕,卻偏偏與公主長得像涡贱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子惹想,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355