天天看點

Linux Shell腳本經典案例(三)

1 從FTP伺服器下載下傳檔案

#!/bin/bash
if [ $# -ne 1 ] ; then
    echo "Usage: $0 filename"
fi
dir = $(dirname $1)
file = $(basename $1)
ftp -n -v << EOF    # -n 自動登入
open 192.168.1.1  # ftp 伺服器
user admin password
binary #設定ftp傳輸模式為二進制,避免MD5值不同或.tar.gz壓縮包格式錯誤
cd $dir
get "$file"
EOF
           

2 連續輸入5個100以内的數字,統計和、最小和最大

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

3 将結果分别指派給變量

應用場景,希望将執行結果或者位置參數指派給變量,以便後續使用

方法一

for i in $(echo "4 5 6");do
    eval a$i = $i
done
echo $a4 $a5 $a6
           

方法二:将位置參數192.168.1.1{1,2}拆分為到每個變量

num = 0 
for i in $(eval echo $*);do
    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
           

方法三

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

4 批量修改檔案名

示例:

# touch article_{1..3}.html

ls
           

目的:把article改為bbs

方法一

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
           

方法二

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

方法三

rename article bbs *.html
           

5 統計目前目錄中以.html結尾的檔案大小

方法一

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

方法二

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

6 掃描主機端口狀态

#!/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實作SSH面互動執行指令

Expect 是一個自動互動式應用程式的工具,如telnet ,ftp ,passwd 等。

需要先安裝expect軟體包

方法一 :EOF标準輸出作為expect标準輸入

#!/bin/bash
USER = root
PASS = 123
IP = 192.168.1.1
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
           

方法二

#!/bin/bash
USER = root
PASS = 123
IP = 192.168.1.1
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}
    }
"
           

方法三:将expect腳本獨立出來

登入腳本

#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 { $argv != 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 "$password\r"}
}

expect "$user@*" {send "$cmd\r"}
expect "$user@*" {send "exit\r"}
expect eof
           

執行指令腳本:寫個循環可以批量操作多台伺服器

#!/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主機SSH連接配接資訊:

#cat user_info.txt
192.168.1.1 root 123
           

8 批量修改伺服器使用者密碼

Linux主機SSH連接配接資訊:舊密碼

# cat old_pass.txt
192.168.10.1 root 123 22
192.168.10.2 root 123 22
           

内容格式:IP User Password Port

SSH遠端修改密碼腳本:新密碼随機生成

#!/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) #随機密碼
    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
           

9 列印乘法口訣

方法一

awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++<n;)printf i"x"n"="i*n "  ";print "  "}}'
           

方法二

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工具完善腳本指令行參數

getopts是一個解析腳本選項參數的工具

指令格式:getopts optstring name[arg]

初次使用,要注意以下幾點:

1 腳本位置參數會與optstring中的單個字母逐個比對,如果比對到就指派給name,否則指派name為問号

2 optstring中單個字母是一個選項,如果字母後面加冒号,表示該選項後面帶參數,參數值并會指派給OPTARG變量

3 optstring中第一個是冒号,表示屏蔽系統錯誤(test.sh:illegal option --h)

4 允許把選項放一起,例如:-ab

例子:

#!/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
           

原文連結

繼續閱讀