第二十二天笔记
if 条件语句的知识与实践
if 条件语句
if 条件语句的语法
if条件语句,其语义类似于汉语里的"如果...那么"。
单分支结构
bash
if <条件表达式>;then
指令
fi
双分支结构
if条件语句的双分支结构主体则为:"如果...,那么...,否则..."。
bash
if <条件表达式>;then
指令集1
else
指令集2
fi
多分支结构
if条件语句多分支结构的主体为:"如果...,那么...,否则如果...,那么,否则如果...,那么...,否则..."。
elif可多个
bash
if <条件表达式1>;then
指令
elif <条件表达式2>;then
指令
elif <条件表达式3>;then
指令
else
指令
fi
if 条件语句多种条件表达式语法
[]条件表达式
bash
if [ 字符串 或 算术表达式 ];then
指令
fi
[[]]条件表达式
bash
if [[ 字符串 或 算术表达式 ]];then
指令
fi
(())条件表达式
bash
if ((算术表达式));then
指令
fi
if 条件语句实践
检测sshd服务是否运行,如果未运行则启动sshd服务
bash
#!/bin/bash
systemctl is-active sshd &>/dev/null
if [ $? -ne 0 ];then
echo "sshd is not running, I'll start sshd."
systemctl start sshd
fi
检测sshd服务是否运行,如果未运行则启动sshd服务;如果运行,输出 "Running"。
bash
#!/bin/bash
systemctl is-active sshd &>/dev/null
if [ $? -ne 0 ];then
echo "sshd is not running."
echo -n "Starting sshd ... ..."
systemctl start sshd && echo DONE
else
echo "sshd is running"
fi
通过传参控制sshd服务
bash
#!/bin/bash
if [ "$1" == "start" ];then
systemctl start sshd
elif [ "$1" == "stop" ];then
systemctl stop sshd
elif [ "$1" == "status" ];then
systemctl status sshd
elif [ "$1" == "restart" ];then
systemctl restart sshd
else
echo "Usage: $0 start|stop|status|restart "
fi
Shell 函数的知识与实践
Shell 函数介绍
函数也有类似于别名的作用,例如可简化程序的代码量,让程序更易读、易改、易用。
Shell 函数的语法
bash
function 函数名 () {
指令...
return n
}
简化写法1:不写()
bash
function 函数名 {
指令...
return n
}
Shell 函数的执行
bash
函数名 参数1 参数2
函数后接参数的说明:
- Shell 的位置参数(1、 2 ... 、 2...、 2...、#、 ∗ 、 \*、 ∗、?及@)都可以作为函数的参数来使用。
- 此时父脚本的参数临时地被函数参数所掩盖或隐藏。
- $0 比较特殊,它仍然是父脚本的名称。
Shell 函数的基础实践
hello函数
bash
[laoma@laoma-shell ~]$ cat fun1.sh
#!/bin/bash
function hello () {
echo "Hello World !"
}
hello
[laoma@laoma-shell ~]$ bash fun1.sh
Hello World !
# 函数必须先定义,后调用
[laoma@laoma-shell ~]$ cat fun2.sh
#!/bin/bash
hello
function hello () {
echo "Hello World !"
}
[laoma@laoma-shell ~]$ bash fun2.sh
fun2.sh: line 2: hello: command not found
调用外部函数
bash
[laoma@laoma-shell ~]$ cat >> mylib << 'EOF'
function hello () {
echo "Hello World !"
}
EOF
[laoma@laoma-shell ~]$ cat fun3.sh
#!/bin/bash
if [ -r mylib ];then
source mylib
else
echo mylib is not exist
exit 1
fi
hello
[laoma@laoma-shell ~]$ bash fun3.sh
Hello World !
带参数的函数
bash
[laoma@laoma-shell ~]$ cat fun4.sh
#!/bin/bash
function print () {
if [ "$1" == "PASS" ];then
echo -e '\033[1;32mPASS\033[0;39m'
elif [ "$1" == "FAIL" ];then
echo -e '\033[1;31mFAIL\033[0;39m'
elif [ "$1" == "DONE" ];then
echo -e '\033[1;35mDONE\033[0;39m'
else
echo "Usage: print PASS|FAIL|DONE"
fi
}
read -p "请输入你想要打印的内容:" str
print $str
[laoma@laoma-shell ~]$ bash fun4.sh
请输入你想要打印的内容:`PASS`
PASS
[laoma@laoma-shell ~]$ bash fun4.sh
请输入你想要打印的内容:hello
Usage: print PASS|FAIL|DONE
hello函数
bash
[laoma@laoma-shell ~]$ cat fun5.sh
#!/bin/bash
function print () {
if [ "$1" == "PASS" ];then
echo -e '\033[1;32mPASS\033[0;39m'
elif [ "$1" == "FAIL" ];then
echo -e '\033[1;31mFAIL\033[0;39m'
elif [ "$1" == "DONE" ];then
echo -e '\033[1;35mDONE\033[0;39m'
else
echo "Usage: $0 PASS|FAIL|DONE"
fi
}
str=$2
print $str
# 结果表明,脚本的第一个参数并没有传递给脚本内部函数。
[laoma@laoma-shell ~]$ bash fun5.sh PASS FAIL
FAIL
# 结果表明,$0 仍然使用脚本名,而非函数名。
[laoma@laoma-shell ~]$ bash fun5.sh
Usage: fun5.sh PASS|FAIL|DONE
函数的递归调用
求1+2+3+...+10 的和
bash
#!/bin/bash
function sum_out() {
if [ $1 -eq 1 ];then
sum=1
else
sum=$[ $1 + $(sum_out $[ $1 - 1 ] ) ]
fi
echo $sum
}
read -p "输入一个你想计算和的整数:" num
sum_out $num
case 条件语句的应用实践
case 条件语句的语法
bash
case "变量值" in
值1)
指令1...
;;
值2)
指令2...
;;
*)
指令3...
;;
esac
case 条件语句实践
判断用户输入的数字是否是1、2、3。
bash
[laoma@laoma-shell ~]$ cat case1.sh
#!/bin/bash
read -p "请输入一个1-3之间数字:" num
case $num in
1)
echo "您输入的数字是:$num"
;;
2)
echo "您输入的数字是:$num"
;;
3)
echo "您输入的数字是:$num"
;;
*)
echo "请输入一个1-3之间数字。"
;;
esac
# 执行验证
[laoma@laoma-shell ~]$ bash case1.sh
请输入一个1-3之间数字:1
您输入的数字是:1
[laoma@laoma-shell ~]$ bash case1.sh
请输入一个1-3之间数字:4
请输入一个1-3之间数字。
实践:给输出的字符串加颜色
bash
[laoma@laoma-shell ~]$ cat case2.sh
#!/bin/bash
case $1 in
PASS)
echo -e '\033[1;32mPASS\033[0;39m'
;;
FAIL)
echo -e '\033[1;31mFAIL\033[0;39m'
;;
DONE)
echo -e '\033[1;35mDONE\033[0;39m'
;;
*)
echo "Usage: $0 PASS|FAIL|DONE"
;;
esac
case 语句企业级生产案例
控制sshd服务
#!/bin/bash
case $1 in
start)
systemctl start sshd
;;
stop)
systemctl stop sshd
;;
restart | reload )
systemctl restart sshd
;;
status )
systemctl status sshd
;;
*)
echo "Usage: case-ssh start|stop|restart|reload|status"
;;
esac
简化版:
bash
#!/bin/bash
case $1 in
start | stop | restart | reload | status)
systemctl $1 sshd
;;
*)
echo "Usage: case-ssh start|stop|restart|reload|status"
;;
esac
管理用户
通过传参的方式往 /etc/users 里添加用户,具体要求如下。
-
命令用法为:
Usage: user-mgr [ -add | -del | -search ] username
-
传参要求为:
参数为-add时,表示添加后面接的用户名。如果有同名的用户, 则不能添加。
参数为-del时,表示删除后面接的用户名。如果用户不存在,提示用户不存在。
参数为-search时,表示查找后面接的用户名。 如果用户不存在,提示用户不存在。
没有用户时应给出明确提示。
bash
#!/bin/bash
# run as root
[ $UID -ne 0 ] && echo 'Please run as root' && exit 1
# create users file
users_info_file=/etc/users
[ -f ${users_info_file} ] || touch ${users_info_file}
# provides two args
if [ $# -ne 2 ];then
echo "Usage: user-mgr [ -add | -del | -search ] username"
exit 2
fi
# get arg value
action=$1
username=$2
# manager user
case $action in
-search)
if grep -q "username: $username" ${users_info_file};then
echo "$username is exist."
else
echo "$username is not exist."
fi
;;
-add)
if grep -q "username: $username" ${users_info_file};then
echo "$username is exist."
else
chattr -i ${users_info_file}
echo "username: $username" >> ${users_info_file}
echo "$username has been added."
chattr +i ${users_info_file}
fi
;;
-del)
if grep -q "username: $username" ${users_info_file};then
chattr -i ${users_info_file}
sed -i "/username: $username/d" ${users_info_file}
chattr +i ${users_info_file}
echo "$username has been deleted."
else
echo "username: $username" >> ${users_info_file}
fi
;;
*)
echo "Usage: user-mgr [ -add | -del | -search ] username"
;;
esac