Shell programming syntax and Application

brief introduction

Shell scripts are similar to batch processing under Windows/Dos, that is, they are pre-loaded into a file with various commands to facilitate one-time execution of a program file, mainly for administrator setup or management purposes.However, it is more powerful than batch processing under Windows and more efficient than programs edited with other programs, using commands under Linux/Unix

variable

Variable type
 Local variable: current user process
 Environment variables: current user process and subprocess (env/set)
Global variable: All user programs can call
 System variables: built-in bash variables
    $?: Last command execution returned status; 0 means normal execution, non-0 means abnormal execution
    $#: Indicates the number of parameters for a script connection
    $*: Represents all parameters after the script
    $@: Represents all parameters after the script
    $0: Name of the running script
    -: Indicates the position parameter after the script
    $$: Process number of the current process
    $!: Last process number to run in the background
    !$: Parameters that invoke the last command

array

Normal array (integer as subscript)
    Defined separately: array[0]=v1 array[1]=v2...
    Continuous definition: array= (var1 var2... Varn)
    Array=(`cat/etc/passwd`) is separated by spaces
    View a single element: ${array[0]}
    View all elements:
        ${array[*]}
        ${array[@]}
    Intercept some elements: ${array[*]:1:3}
    View number of elements: ${#array[*]}
    Get the element subscript:
        ${!array[*]}
        ${!array[@]}
Associated Array (string can be used as subscript, declared in definition first)
    Definition: declare-A array
    View associated array declare-A
    Defined separately: array[a]=v1 array[b]=v2...
    Continuous definition: array=([name1]=var1 [name2]=var2... [namen]=varn)
    View individual elements: ${array[a]}
    View all elements:
        ${array[*]}
        ${array[@]}
    Intercept some elements: ${array[*]:1:3}
    View number of elements: ${#array[*]}
    Get the element subscript:
        ${!array[*]}
        ${!array[@]}
    Operation (default 0):
        let array[name1]++
        let array[name1]+=num
 Empty Array
    unset array

usage

Magic Bytes (Wildcard)

#!/bin/env bash

View Running Processes

[root@localhost ~]# bash -x my.sh

View process ID

[root@localhost ~]# pgrep process name &>/dev/null

View grammar problems

[root@localhost ~]#     bash -n my.sh

date tool

Last minute (day, week, month, year)
    date -d '-1 minute'
The next minute
    date -d '1 minute'
Format
    date +%d/%b%Y:%H%M

grammar

Invoke a part of a variable

A=123456
echo ${A:2:3}=>345

Delete a part of a string

Delete from back to front
    ${array%xxx}

Read variables from files

read -p "Input:" name  < filename

Define variable of type, restrict variable

declare [options] variable name = variable value
 Common Options
 -i: Declare an integer
 -r: Declares a readonly variable whose value cannot be changed and cannot be unset
 -a:Declare an array
 -x:Declare environment variables

Four operations (integers only)

$((1+1))
$[10-5]
Expr 1 + 1 (not exponentially)
N=1; let n=n+1; echo $n (variable needs to be defined first)

shift

Move the position parameter left (default 1 bit) or set it to multiple bits

Remove the directory and name of the current file

dirname $A
basename $A

shift

#Input parameter one two three four five six
#Shift means how many arguments are removed by right shift
echo "The script name is ==> ${0} "
echo "Total parameter number is ==> $# "
echo "Your whole parameter is ==> '$@' "
shift #shift a variable
echo "Total parameter number is ==> $# "
echo "Your whole parameter is ==> '$@' "
shift 3 #A second shift of three variables
echo "Total parameter number is ==> $# "
echo "Your whole parameter is ==> '$@' "

Variable Content Delete and Replace

url=www.haha.com
 Get Length: ${$url}
Remove a key from left to right: ${url#*.}=>Haha.com
 Leave left to right to remove as much as possible: ${url##*.}=>com
 Remove one key from right to left: ${url%*.}=>Www.haha
 Strip right to left to remove maximum: ${url%*.}=>www

Concurrent Execution

Wrap function body with {} & and add wait keyword

Implement Output

cat << -EOF
xx
EOF

Random Numbers (0-32767)

$RANDOM
 Generate random numbers between 0-n-1
    $[$RANDOM%n]
Generate 10-99
    $[$RANDOM%90+10]

Expect (for automatic response)

#Location parameter defines variables
set ip xxx
set pass xxx
#Start a program
spawn ssh root@$ip
#Capture the appropriate content
#Exp_The continue parameter indicates that this capture can be ignored
expect {
    "(yes/no)?" { send "yes\r";exp_continue }
    "password:" { send "$pass\r";exp_continue }
}
#Perform operations
expect "#"
send "rm -rf /tmp/*\r"
send "hostname\r"
send "date +%F\r"
send "touch file{1..3}\r"
send "ls /tmp/\r"
expect eof

Conditional Judgment

grammar
    test condition
    [Conditions]
    [[Conditions]]
Class C Style
    Numerical comparison: ((condition))
The difference between [] and []]
    When determining an empty string, [] needs to add''to the variable; [[]] does not need
    To separate multiple conditions, [[]] does not need to

Process Control

if structure

grammar
    if [[ condition1 ]];then
        command1
      elif [[ condition2 ]];then
        command2
      else
        command3
    fi 

for structure

grammar
    With List:
    for variable in {list}
       do   
        command
       done
    No list (determined by user input, $1):
    for variable [in "$@"]
    Class C style:
    for (( expr1;expr2;expr3 )) 

while structure

grammar
    while expression
      do
        command
      done

until structure

grammar
    until expression
      do
        command
      done

case statement

grammar
    case var in
    pattern 1)
        command
        ;;
    pattern 2)
        command
        ;;
        *)#Equivalent to default
        command
        ;;
    esac

select loop (easy to output menu, infinite loop)

grammar
    #Define prompt, $PS1,$PS2,$PS3
    PS3="Your choice is:"
    select choice in xxx xxx xxx
    do
        case "$choice" in
            xxx)
        esac
    done

function

grammar
    [function] function name (){
        Function Body
        Print the first parameter passed to the function: echo $1
    }
call
    Terminal temporary call:sourceFunction.sh; function_Name
    Environment variables: function write/etc/bashrc (user in home directory.bashrc)
    Called in script: function_Name (defined in script |source)Function.sh)

application

Requirements: Randomly generate 1,000 139 phone numbers starting with five lucky viewers

n1=0
n2=0
n3=0
n4=0
n5=0
n6=0
n7=0
n8=0
file=/tmp/phonenum.txt
for ((i=1;i<=1000;i++))
do
    for ((j=1;j<=8;j++))
    do
    let n$j=$[$RANDOM%10]
    done
    echo "139$n1$n2$n3$n4$n5$n6$n7$n8" >> $file 
done
#!/bin/env bash
#Draw five lucky viewers
phone=/tmp/phonenum.txt
for ((i=1;i<=5;i++))
do
    line=`wc -l $phone|cut -d ' ' -f1`
    lucky_lines=$[$RANDOM%$line+1]
    #Take out the number
    luck_num=`head -$lucky_lines $phone |tail -1`
    #Replace Display to Screen
    echo "139****${luck_num:7:4}"
    echo $luck_num >> /tmp/luck.txt
    #Delete the extracted number, sed Use double quotes for shell variables
    sed -i "/$luck_num/d" $phone
done

Requirements: Keep logs for the last 3 days

#!/bin/bash
#Realization 1:
#Periodically delete files in the directory that have been modified for more than 7 days, using absolute paths
#Script plus i privileges to prevent misoperation
#Method 1:
`find /path -mtime +7 -exec rm -r {} \;`
#Method 2:
`find /path -mtime +7 |xargs rm -rf `

#Realization two:
#Keep backup files for the first two working days, using absolute paths
#Method 1:
`ls -t /path/*.tar.gz | awk 'NR>2' |xargs rm -rf `
#Method 2:
`ls -t /path/*.tar.gz|awk 'NR>2 {print "rm -f "$0""}'|bash`

Requirements: Statistics website connection status

#!/bin/bash
declare -A state_array
states=`ss -ant|grep :80 |cut -d ' ' -f1`
for i in $states
do
    let state_array[$i]++
done

for j in ${!state_array[*]}
do
    echo $j:${state_array[$j]}
done

Requirements: Script to view system performance

#!/bin/bash
PS3="Your choice is:"
#Judgement System
os_check(){
    if [ -e /etc/redhat-release ];then
        REDHAT=`cat /etc/redhat-release|cut -d ' ' -f1`
    else
        DEBIAN=`cat /etc/issue|cut -d ' ' -f1`
    fi

    if [ "$REDHAT" == "Centos" -o "$REDHAT" == "Red" ];then
        P_M=yum
    elif [ "$DEBIAN" == "Ubuntu" -o "$DEBIAN" == "ubuntu" ];then
        P_M=apt-get
    else
        echo "Operating system does not support."
        exit 1
    fi
}

if [ $LOGNAME != root ];then
    echo "Please use the root account operation."
    exit 1
fi

instll_software(){
if ! which $1  &> /dev/null;then
    echo $1 "command not found,now the install."
    sleep 1
    os_check
    $P_M install $2 -y
    echo "--------------------"
fi
}

while true
do
    select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic quit
    do
        case $input in
            cpu_load)
                #CPU utilization and load
                echo "-------------------------"
                i=1
                while [[ $i -le 3 ]]
                do
                    #define color
                    echo -e "\033[32m reference value ${i}\033[0m"
                    UTIL=`vmstat|awk '{if(NR==3)print 100-$15"%"}'`
                    USER=`vmstat|awk '{if(NR==3)print $13"%"}'`
                    SYS=`vmstat|awk '{if(NR==3)print $14"%"}'`
                    IOWAIT=`vmstat|awk '{if(NR==3)print $16"%"}'`
                    echo "Util:$UTIL"
                    echo "User use:$USER"
                    echo "System use:$SYS"
                    echo "I/O wait:$IOWAIT"
                    let i++
                    sleep 1
                done
                echo "-------------------------"
                break
            ;;
            disk_load)
                #Hard disk I/O load
                echo "-------------------------"
                i=1
                while [[ $i -le 3 ]]
                do
                    echo -e "\033[32m reference value ${i}\033[0m"
                    UTIL=`iostat -x -k|awk '/^[v|s]da/{print $1,$NF"%"}'`
                    READ=`iostat -x -k|awk '/^[v|s]da/{print $1,$4"KB"}'`
                    WRITE=`iostat -x -k|awk '/^[v|s]da/{print $1,$5KB"%"}'`
                    IOWAIT=`vmstat|awk '{if(NR==3)print $16"%"}'`
                    echo "Util:$UTIL"
                    echo "Read:$READ"
                    echo "Write:$WRITE"
                    echo "I/O wait:$IOWAIT"
                    let i++
                    sleep 1
                done
                echo "-------------------------"
                break
            ;;
            disk_use)
                echo "------------------"
                #Hard Disk Utilization
                DISK_TOTAL=`fdisk -l|awk  '/dev\/sda/&& /^Disk.*byte/{print $2"GB"}'`
                USE_RATE=`df |awk '/\/dev\/mapper/{print $5}'`
                for i in $USE_RATE
                do
                    flag=`awk -v num1="$i" -v num2=90% 'BEGIN{print (num1<=num2)?"0":"1" }'`
                    if [ $flag -eq 1 ];then
                        PART=`df -h|awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART=${i}%"
                    fi
                done
                echo "Disk total:${DISK_TOTAL}"
                echo "Use rate:${USE_RATE}"
                echo "--------------------"
                break
            ;;
            disk_inode)
                echo "------------------"
                #Hard disk inode utilization
                USE_RATE=`df -i |awk '/\/dev\/mapper/{print $5}'`
                for i in $USE_RATE
                do
                    flag=`awk -v num1="$i" -v num2=90% 'BEGIN{print (num1<=num2)?"0":"1" }'`
                    if [ $flag -eq 1 ];then
                        PART=`df -h|awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART=${i}%"
                    else
                        echo "UseRate:"${USE_RATE}
                        echo "Inode use rate no than 90% of the partition."
                    fi
                done
                echo "------------------"
                break
            ;;
            mem_use)
                echo "------------------"
                MEM_TOTAL=`free -m|awk '{if(NR==2)printf"%.1f",$2/1024}END{print"G"}'`
                USE=`free -m|awk '{if(NR==2)printf"%.1f",$3/1024}END{print"G"}'`
                FREE=`free -m|awk '{if(NR==2)printf"%.1f",$4/1024}END{print"G"}'`
                CACHE=`free -m|awk '{if(NR==2)printf"%.1f",$6/1024}END{print"G"}'`
                echo "Total:${MEM_TOTAL}"
                echo "Use:${USE}"
                echo "Free:${FREE}"
                echo "Cache:${CACHE}"
                echo "------------------"
                break
            ;;
            tcp_status)
                #Network Connection Status
                echo "------------------"
                COUNT=`ss -ant|awk '!/State/{status[$1]++}END{for (i in status)print i,status[i]}'`
                echo "Tcp connect status:\n$COUNT"
                echo "------------------"
                break
            ;;
            cpu_top10)
                #Top 10 CPU processes
                echo "------------------"
                CPU=`ps -axu|awk '{if($3>0.1) print "PID: "$2" CPU: "$3"% --> "$NF"\n"}'|sort -k4 -nr|head -10`
                num=0
                for i in $CPU
                do
                    echo -n "$i"
                    let num++
                    if [ $num -eq 6 ];then
                        echo
                        let num=0
                    fi
                done
                echo "------------------"
                break
            ;;
            mem_top10)
                #Top 10 processes in memory usage
                echo "------------------"
                MEM=`ps -axu|awk '{if($4>0.1){print "PID: "$2" Memory: "$4"% --> "$NF""}}'|sort -k4 -nr|head -10`
                num=0
                for i in $MEM
                do
                    echo -n "$i"
                    let num++
                    if [ $num -eq 6 ];then
                        echo
                        let num=0
                    fi
                done
                echo "------------------"
                break
            ;;
            traffic)
                #Network flow
                while true
                do
                read -p "Input network cat name (ens[33/37]):" ens
                #Judging whether there is
                if [ `ifconfig |grep -c "\<$ens\>"` -eq 1 ];then
                    break
                else
                    echo "Input error,please input again."
                fi
                done
                echo "---------------------------"
                OLD_RX=`ifconfig ens33 |awk '{if(NR==5)print $5}'`
                OLD_TX=`ifconfig ens33 |awk '{if(NR==7)print $5}'`
                sleep 1
                NEW_RX=`ifconfig ens33 |awk '{if(NR==5)print $5}'`
                NEW_TX=`ifconfig ens33 |awk '{if(NR==7)print $5}'`
                IN=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_RX}-${OLD_RX}))'/1024/1024}'`
                OUT=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_TX}-${OLD_TX}))'/1024/1024}'`
                echo "IN:${IN}MB/s OUT:${OUT}MB/s"
                echo "---------------------------"
                break
            ;;
            quit)
                exit
            ;;
            *)
                echo "---------------------------"
                echo "Input number"
                break
                echo "---------------------------"
            ;;
        esac
    done
done

Tags: Operation & Maintenance network shell Windows Ubuntu

Posted on Sun, 21 Jun 2020 18:11:48 -0400 by theweirdone