source 和 .
# 直接执行脚本, 会在一个子shell中执行脚本
# 脚本执行完毕后, 子shell退出, 在子shell中设置的变量和函数不会影响到父shell环境
./script.sh
设置的变量或者函数都会在当前的shell环境中生效
# 设置的变量或者函数都会在当前的shell环境中生效
source ./script.sh
# 完全等价于 source
. ./script.sh
# 设置的变量或者函数都会在当前的shell环境中生效
source ./script.sh
# 完全等价于 source
. ./script.sh
循环
while
while true
do
echo 1
sleep 3
done
# killall -0 docker-proxy 执行的结果 $? =0 的情况, 才会进入循环
while killall -0 docker-proxy
do
echo 1
sleep 3
done
for
i=0
while [ $i -lt 20 ]
do
for j in '-' '\' '|' '/'
do
printf "intel testing : %s\r" $j
sleep 0.1
((i++))
done
done
a=("a b" "c d" "e")
for ((i=0;i<${#a[*]};i++))
do
echo $i
echo ${a[$i]}
done
函数
获取函数名称
不要用 sh fun.sh 来执行, 否则 没有 $FUNCNAME
#!/bin/bash
show(){
# FUNCNAME 实际是一个数组,包含了当前调用栈上所有函数的名称,先进后出
echo $FUNCNAME # 首个元素是当前函数名
# 可以发现实际有个main 函数, 先main,再调用了show2, 最后show
echo ${FUNCNAME[@]} # show show2 main.
}
show2(){
show
}
show2
bash fun.sh
# 或者
chmod +x fun.sh
./fun.sh
()
- 实现执行脚本时,没有参数直接提示错误, 然后退出脚本
- () 里实际是在子shell里执行命令,它的exit退出,变量修改等操作都不影响当前shell,所以不对
- {} 里面的是在当前shell的, 一组命令作为一个整体执行.
#!/bin/bash
test -z $1 && ( echo "need arg";exit; )
echo ok
#!/bin/bash
test -z $1 && { echo "need arg";exit; }
echo ok
注意 需要{ } 两边空格, 最后 }前面的; 也是需要的
`` 和 $()
t=$(date +%Y) # t=`date +%Y`
echo $t # 2023
shift
#!/bin/bash
echo $* # sh shift.sh a b c d e f
shift # 参数左移一位
echo $1 # 这个时候 第一个参数就是 b
shift 1 # 同 shift
echo $1 # c
shift 3 # 参数左移3 位
echo $1 # 这个时候 $1 是f
getops
getopts 是一个内置命令,用于解析脚本的命令行参数
#!/bin/bash
while getopts ":a:b:" opt; do
case $opt in
a)
echo "选项 -a 被设置为: $OPTARG"
;;
b)
echo "选项 -b 被设置为: $OPTARG"
;;
1 \?)
echo "无效选项: -$OPTARG" >&2
exit 1
;;
2 :)
echo "选项 -$OPTARG 需要一个参数。" >&2
exit 1
;;
esac
done
- 1
-
无效的命令行参数的情况
- 2
-
命令行参数值没有指定的情况
选项 -a 被设置为: aa
选项 -b 被设置为: bb
无效选项: -c
选项 -a 被设置为: aa
选项 -b 需要一个参数。
Back to top