Shell script-functions (including application cases)

Preface

In fact, the function of the shell is very simple. It is a breeze for students who have learned other programming languages.

What is a function

  • The shell allows a set of commands or statements to form a piece of usable code, these code blocks are called shell functions

  • Give this piece of code a name called the function name, and then you can directly call the function of this piece of code

  • Code modularization can be used to define functions in the shell to facilitate code reuse

  • Functions must be defined before they can be used

How to define a function

method one

函数名()
{
    
    
  函数体(一堆命令的集合,来实现某个功能)   
}

Method Two

function 函数名()
{
    
    
   函数体(一堆命令的集合,来实现某个功能)
}

Familiar with function writing

  1. factorial
#!/bin/bash
factorial() {
    
    
factorial=1
for((i=1;i<=5;i++))
do
        factorial=$[ $factorial * $i ]
        echo "$factorial"
done
echo "5的阶乘是:$factorial"
}
factorial

#!/bin/bash
function factorial {
    
    
a=1
for ((i=1;i<=10;i++))
do
        a=$[ $a * $i ]
        echo "$a"
done
echo "10的阶乘是:$a"
}
factorial
  1. Transfer parameters
#!/bin/bash
factorial() {
    
    
factorial=1
for((i=1;i<=$1;i++))
do
        factorial=$[ $factorial * $i ]
        echo "$factorial"
done
echo "$1 的阶乘是:$factorial"
}

factorial $1
factorial $2
factorial $3

# 执行函数
bash factorial.sh 10 8 5
10 的阶乘是:3628800
8 的阶乘是:40320
5 的阶乘是:120


#!/bin/bash
factorial() {
    
    
a=1
for i in `seq $1`
do    
        let a*=$i				
        echo "$a"
done
echo "$1 的阶乘是:$a"
}

factorial $1

# 执行函数
[root@maomao ~]# bash cheng.sh 10
1
2
6
24
120
720
5040
40320
362880
3628800
10 的阶乘是:3628800


#!/bin/bash
fun () {
    
    
read -p "请输入一个数字计算他的阶乘:" num 
fun=1
for((i=1;i<=$num;i++))
do
        fun=$[ $fun * $i ]
        echo "$fun"
done

}
fun $num

Function return value

  • The function return value is a functionLast command
  • The highest return value of the shell is255
#!/bin/bash
re() {
    
    
read -p "enter num:" num 
return $[2*$num]
}

re
echo "re return value:$?"


#!/bin/bash
fun() {
    
    
read -p "enter num:" num 
echo $[2*$num]
}

result=`fun`
echo "fun return value:$result"		
#这个返回值不是真的返回值

FunctionreturnDescription:

  • Return can end a function. Similar to the loop control statement break (end the current loop and execute the code behind the loop body).
  • By default, return returns the status value of the last command in the function. The parameter value can also be given, and the range is between 0-256.
  • If there is no return command, the function will return the exit status value of the last command.

return can end a function

#!/bin/bash
fun(){
    
    
	echo 'maomao'
	echo 'zhuzhu'
	return
	echo 'niuniu'
}
fun

# 执行脚本
[root@maomao ~]# bash test.sh
maomao
zhuzhu

return returns the status value of the last command in the function by default

#!/bin/bash
fun(){
    
    
	echo 'zhuzhu'
	echo 'maomao'
	return 88
	echo 'niuniu'
}
fun

# 执行脚本
[root@maomao ~]# bash test1.sh
zhuzhu
maomao
[root@maomao ~]# echo $?
88

Function parameter passing positional parameter

#!/bin/bash
if [ $# -ne 3 ];then
        echo "useage:`basename $0` par1 par2 par3"
        exit
fi

fun3() {
    
    
        echo "$(($1 * $2 * $3 ))" 
}

result=`fun3 $1 $2 $3`		这个$1 $2 $3是外面的参数赋给函数里的$1 $2 $3
echo "$result"				你传给程序 程序传给函数

# 执行脚本
[root@maomao ~]# bash parameter.sh 1 2 3
6
[root@maomao ~]# bash parameter.sh 2 3 4
24

如果result=`fun3 $3 $3 $3`  	三个$3相乘 3*3*3
[root@maomao ~]# bash parameter.sh 1 2 3
27

Function parameter group variable

Calculate the multiplication of the values ​​in the array

#!/bin/bash
num1=(1 2 3 4 5)
num2=(2 4 6 8 10) 
array() {
    
    
        local array=1
        for i in $*
        do  
                array=$[ array * $i ]
        done
        echo "$array"
}

array ${num1[*]}    
array ${num2[@]}

# 执行脚本
[root@maomao ~]# bash array.sh 
120
3840

Array passing parameters becomes a new array

#!/bin/bash
num=(1 2 3 4 5)
num2=(2 4 6 8 10)
array() {
    
    
        local newarray=($*)
        local i
        for((i=0;i<$#;i++))
        do  
                outarray[$i]=$(( ${newarray[$i]} * 5 ))
        done
        echo "${outarray[*]}"
}
result=`array ${
     
     num[*]}`
echo ${result[*]}

result=`array ${
     
     num2[@]}`
echo ${result[@]}

# 执行脚本
[root@maomao ~]# bash array1.sh
5 10 15 20 25
10 20 30 40 50

Change the value of the original array

#!/bin/bash
num=(2 4 6 8 10)
array() {
    
    
        local newarray=()
        local i
        for i
        do
                newarray[i++]=$[ $i * 10 ]
        done
        echo "${newarray[*]}"

}
result=`array ${
     
     num[*]}`
echo "${result[*]}"

# 执行脚本
[root@maomao ~]# bash array2.sh 
20 40 60 80 100


  • The function accepts positional parameters $1 $2 $3… $n
  • The function accepts array variables $@ $*
  • The function will receive all the parameters assigned to the array newarry=($*)

Applications

  1. Write a script to collect the basic information (name, gender, age) entered by the user, if you do not enter it, you will always be prompted to enter
  2. Finally, output the corresponding content according to the user's information
#!/bin/bash
#该函数实现用户如果不输入内容则一直循环直到用户输入为止,并且将用户输入的内容打印出来
input_fun()
{
    
    
  input_var=""
  output_var=$1
  while [ -z $input_var ]
    do
    	read -p "$output_var" input_var
    done
    echo $input_var
}

input_fun 请输入你的姓名:

或者
#!/bin/bash
fun()
{
    
    
    read -p "$1" var
    if [ -z $var ];then
        fun $1
    else
        echo $var
    fi
}


#调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
name=$(input_fun 请输入你的姓名:)
sex=$(input_fun 请输入你的性别:)
age=$(input_fun 请输入你的年龄:)

#根据用户输入的性别进行匹配判断
case $sex in
            man)
            if [ $age -gt 18 -a $age -le 35 ];then
                echo "中年大叔你油腻了吗?加油"
            elif [ $age -gt 35 ];then
                echo "保温杯里泡枸杞"
            else
                echo "年轻有为。。。"
            fi
            ;;
            woman)
            xxx
            ;;
            *)
            xxx
            ;;
esac

Comprehensive case

Task background
Although the existing springboard has realized a unified entrance to access the production server, the yunwei user has too much authority to operate all the directory files on the springboard, and there is a security risk of accidental deletion of data, so I hope you make some security strategies to ensure the springboard The normal use of the machine.

Specific requirements

  1. Only allow yunwei users to remotely connect to the background application server through the springboard to do some maintenance operations
  2. When the company's operation and maintenance personnel remotely connect to the springboard through a yunwei user, the following menu will pop up for selection:
欢迎使用Jumper-server,请选择你要操作的主机:
3. DB1-Master
4. DB2-Slave
5. Web1
6. Web2
h. help
q. exit
  1. When the user selects the corresponding host, the direct login without password is successful
  2. If the user does not input, the user will be prompted for input until the user chooses to log out

Comprehensive analysis

  1. Put the script in the .bashrc file in the yunwei user's home directory (/shell05/jumper-server.sh)
  2. Define the menu as a function [Print Menu], which is convenient for later calling
  3. Use the case statement to realize the user's choice [define variables interactively]
  4. When the user selects a certain server, further ask the user what needs to be done case...esac interactively define variables
  5. Use loops to realize that users don't choose to keep choosing
  6. Restrict users to directly close the terminal exit after exiting
#!/bin/bash
# jumper-server
# 定义菜单打印功能的函数
menu()
{
    
    
cat <<-EOF
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master
2. DB2-Slave
3. Web1
4. Web2
h. help
q. exit
    EOF
}
# 屏蔽以下信号
trap '' 1 2 3 19
# 调用函数来打印菜单
menu
#循环等待用户选择
while true
do
# 菜单选择,case...esac语句
read -p "请选择你要访问的主机:" host
case $host in
    1)
    ssh [email protected]
    ;;
    2)
    ssh [email protected]
    ;;
    3)
    ssh [email protected]
    ;;
    h)
    clear;menu
    ;;
    q)
    exit
    ;;
esac
done


将脚本放到yunwei用户家目录里的.bashrc里执行:
bash ~/jumper-server.sh
exit

Further improve the demand
In order to further enhance the safety of the springboard, the staff visit the production environment through the springboard, but cannot stay on the springboard.

#!/bin/bash
#公钥推送成功
trap '' 1 2 3 19
#打印菜单用户选择
menu(){
    
    
cat <<-EOF
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master
2. DB2-Slave
3. Web1
4. Web2
h. help
q. exit
EOF
}

#调用函数来打印菜单
menu
while true
do
read -p "请输入你要选择的主机[h for help]:" host

#通过case语句来匹配用户所输入的主机
case $host in
    1|DB1)
    ssh [email protected]
    ;;
    2|DB2)
    ssh [email protected]
    ;;
    3|web1)
    ssh [email protected]
    ;;
    h|help)
    clear;menu
    ;;
    q|quit)
    exit
    ;;
esac
done

自己完善功能:
1. 用户选择主机后,需要事先推送公钥;如何判断公钥是否已推
2. 比如选择web1时,再次提示需要做的操作,比如:
clean log
重启服务
kill某个进程

supplement

1) SIGHUP             重新加载配置    
2) SIGINT            键盘中断^C
3) SIGQUIT          键盘退出
9) SIGKILL             强制终止
15) SIGTERM            终止(正常结束),缺省信号
18) SIGCONT           继续
19) SIGSTOP           停止
20) SIGTSTP         暂停^Z

Guess you like

Origin blog.csdn.net/Cantevenl/article/details/115306150