shell 开头
#!/bin/bash
常规的shell操作,只要会以下几部分,即可正常完成shell编写
1执行顺序
脚本顺序执行,原来怎么敲命令的就怎么写
2 变量赋值
# 变量赋值时等号两边不能有空格
# 单引号是固定字符串
pa='string'
# 双引号可包含变量
pb="ps is ${pa}"
# 接受命令返回
pc=`ls -alh`
3 数组遍历
arr=(aa bb cc dd ff)
# 通过下标访问
for ((i=0; i<5; i++))
do
echo “$i: KaTeX parse error: Expected '}', got 'EOF' at end of input: {arr[i]}”
done
# 遍历访问
for s in ${arr[@]}
do
echo " $s"
done
# 空格分隔的字符串也能遍历,但是不能像上面的方式一样用下标访问元素
arr2='a1 a2 a3 a4 a5'
for s in ${arr2}
do
echo ${s}
done
4条件判断
# shell 脚本都是指令,if 的语句一定要注意空格
# 第一种写法,下面输出 ok
if [[ 10 -gt 3 ]]; then echo ok; else echo no; fi
# 第二种, ** 注意(): 下面输出 ok
if [ 2 > 3 ]; then
echo ok
fi
# 第三种, 下面输出 no
if [[ 2 > 3 ]]
then
echo ok
else
echo no
fi
5定义函数
res=0
echo $res
add() {
((res = $1 + $2))
}
add 12 13
echo $res
$? 说明
# $?接受的是上一条命令执行后的返回值
ls /home
# 下面的输出是 0
echo $?
testReurn() {
return 8
}
testReurn
# 下面的输出是 8
echo $?
6 字符串操作
a='stringA'
b='stringB'
# 判断是否相等,下面输出 no
if [[ $a == $b ]]; then echo yes; else echo no; fi
# 字符串拼接, 下面输出 yes
if [[ 'stringAstringB' == "${a}${b}" ]]; then echo yes; fi
# 取字符串长度, 下面输出 7
echo ${#a}
# 截取字符串, 下面输出 string, ing
echo "${a:0:6}, ${a:3:3}"
# 判断两个字符串是否有相同前缀, 下面输出 yes
if [[ ${a:0:5} == ${b:0:5} ]]; then echo yes; else echo no; fi
# 字符串切分为数组, IFS 变量指定分隔符, 分隔符前后空格会被略去
IFS=, read -r -a arr <<< 'a,b ,c, d,g e, ss'
for str in ${arr[@]}; do echo "'${str}'"; done
文件和目录判断
if [[ -f $filename ]]; then
echo "$filename 是一个文件"
elif [[ -d $filename ]]; then
echo "$filename 是一个目录"
elif [[ -p $filename ]]; then
echo "$filename 是一个管道文件"
elif [[ -S $filename ]]; then
echo "$filename 是一个 sokcet 文件"
elif [[ -b $filename ]]; then
echo "$filename 是 block device"
elif [[ -c $filename ]]; then
echo "$filename 是 character device"
fi
if [[ -L $filename ]]; then
echo "$filename 是一个软链接"
fi
# 对于软链接,使用-L测试时,当链接指向的目标文件不存在时会返回false
if [[ -L $filename || -e $filename ]]; then
echo "$filename 存在 (可能是失效的链接)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename 是失效的软链接"
fi
内容既输出到控制台也输出到文件里
echo 'ok'| tee -a bb.log
处理退出信号
trap "rm -f ${lock_file}; echo 'exited ok.'" SIGINT SIGQUIT
# SIGHUP:从终端终止或退出正在前台运行的进程
# SIGINT:从键盘按下 Ctrl-C
# SIGQUIT:从键盘按下 Ctrl-\
# SIGTERM :软件终止信号
处理参数
if [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX ( brew install gnu-getopt )
getopt_cmd="$(brew --prefix gnu-getopt)/bin/getopt"
else
# linux-gnu
getopt_cmd="getopt"
fi
long_opts="once,name:,note:"
opts=$($getopt_cmd -n $0 -o - --long $long_opts -- "$@")
eval set -- "$opts"
while :
do
case "$1" in
--once)
once="true" ; shift 1 ;;
--name)
name=$2 ; shift 2 ;;
--note)
note=$2 ; shift 2 ;;
--)
shift ; break ;;
*)
echo "参数错误" ; exit 1 ;;
esac
done
echo "once: ${once:-no}, name: ${name}, note: ${note}"
MySQL 查询
std_log='/var/log/test.log'
err_log='/var/log/test.err.log'
user='root'
pwd=''
host='127.0.0.1'
db='mysql'
exec_sql() {
echo "exec_sql: $1" | tee -a ${std_log}
mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "$1" | tee -a ${std_log}
}
exec_sql "show databases"
7 标准输入输出重定向
shell中,每个进程都和三个系统文
件相关联:标准输入stdin,标准输出stdout和标准错误stderr,三个系统文件的文件描述符分别为0, 1, 2
在使用 mysql 命令获取结果时会有一些警告信息
mysql: [Warning] Using a password on the command line interface can be insecure.
但是我要得到命令的结果不需要这些警告, 这个时候就需要重定向错误输出到其他地方
num=`mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "${count_sql}" 2>${err_log}