1,特殊位置变量
1,$0
获取当前执行的shell脚本的文件名,如果执行脚本包含了路径,那么就包括脚本的路径
2,$n
获取当前执行的shell的第n个参数,n=1..9,当n为0时表示脚本的文件名,如果n大于9,则用大括号括起来,例如{1..10},接的参数以空格隔开
3,$#
获取当前执行shell脚本后面接的参数的总个数
3.1例子
[root@onetree-test001 /server/test]# sh q.sh {a..z}
a b c d e f g h i
26
[root@onetree-test001 /server/test]# cat q.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9
echo $#
3.2 判断语句例子
[root@onetree-test001 /server/test]# cat t1.sh
#!/bin/bash
[ $# -ne 2 ] && { #若执行传参的个数不等于2
echo "muse two args"
exit 1
}
echo shunmai
[root@onetree-test001 /server/test]# sh t1.sh
muse two args
3.3 if判断语句
[root@onetree-test001 /server/test]# cat t2.sh
#!/bin/bash
if [ $# -ne 2 ]
then
echo "USAGE:/bin/bash $0 arg1 arg2" #给用户提示正确的用法,此处的$0.打印脚本的名字和路径
exit 1
fi
echo $1 $2 #若参数满足条件,则打印$1.$2获取传参的字符串
[root@onetree-test001 /server/test]# sh t2.sh
USAGE:/bin/bash t2.sh arg1 arg2
[root@onetree-test001 /server/test]# sh t2.sh langwenke shunmai
langwenke shunmai
4,$*
获取当前shell脚本所有传参的参数,不加引号和$@相同:如果给$*加上双引号,例如: "$*",则表示将所有的参数视为单个字符串,相当于"$1 $2 $3"
4.1 例子
[root@onetree-test001 /server/test]# set -- "I am" handsome shunmai. #通过set设置三个字符串参数,"--"表示清除所有的参数变量,重新设置后面的参数变量
[root@onetree-test001 /server/test]# echo $# #传参总数
3
[root@onetree-test001 /server/test]# echo $1
I am
[root@onetree-test001 /server/test]# echo $2
handsome
[root@onetree-test001 /server/test]# echo $3
shunmai.
4.1.1 测试$* $@ 不加双引号
[root@onetree-test001 /server/test]# echo $* #打印$*
I am handsome shunmai.
[root@onetree-test001 /server/test]# echo $@ #打印$@
I am handsome shunmai.
[root@onetree-test001 /server/test]# for i in $* ;do echo $i ;done #使用for循环输出$*测试
I # ($*)不加引号会输出所有参数,第一个参数"I am" 也被分开
am
handsome
shunmai.
[root@onetree-test001 /server/test]# for i in $@ ;do echo $i ;done #使用for循环输出$@测试
I ## ($@)不加引号会输出所有参数,第一个参数"I am" 也被分开
am
handsome
shunmai.
4.1.2测试$* $@ 加双引号
[root@onetree-test001 /server/test]# echo "$*"
I am handsome shunmai.
[root@onetree-test001 /server/test]# echo "$@"
I am handsome shunmai.
[root@onetree-test001 /server/test]# for i in "$*" ;do echo $i ;done
#有双引号的情况下$*,参数里引号的内容被当成一个内容输出
I am handsome shunmai.
[root@onetree-test001 /server/test]# for i in "$@" ;do echo $i ;done
#再有引号的情况下,每个内容单独输出
I am #有引号算一个参数
handsome
shunmai.
[root@onetree-test001 /server/test]# for i ;do echo $i ;done
I am #去掉in变量列表,相当于有引号的in "$@"
handsome
shunmai.
5. $@
获取当前shell脚本所有传参的参数,不加引号和$@相同;如果给$@加上双引号 例如"$@"则表示将所有的参数视为不同的独立字符串,相当于"$1" "$2" "$3" "..." ,这是将多参数传递给其他程序的最佳方法,因为它会保留所有的内嵌在每个参数里的任何空白。当"$@" 和 "$*" 都加双引号时,两者是有区别的;
都不加双引号,两者无区别
位置变量
1, $?
获取执行上一个命令的执行状态返回值(0为成功,非零为失败)
2,$$
获取当前执行的shell脚本的进程号(PID)
[root@onetree-test001 /server/test]# cat test_pid.sh
#!/bin/bash
echo $$ > /tmp/a.pid
sleep 30
[root@onetree-test001 /server/test]# sh test_pid.sh
[root@onetree-test001 ~]# ps -ef |grep test_pid|grep -v grep
root 3686 15452 0 17:13 pts/1 00:00:00 sh test_pid.sh
[root@onetree-test001 ~]# cat /tmp/a.pid
3686
例子
有时执行定时任务脚本的频率比较快,并不知道上一个脚本是否真的执行完毕,但是,业务要求同一时刻只能执行一个同样的脚本在运行,此时可以通过$$获取上一个运行的脚本的进程号,当程序重新运行时根据获得的进程号,清理掉上一个进程,并运行新的脚本命令
#!/bin/bash
pidpath=/tmp/a.pid
if [ -f "$pidpath"]
then
kill`cat $pidpath` >/dev/null 2>&1
rm -f $pidpath
fi
echo $$ > $pidpath
sleep 30
3,$!
获取上一个在后台工作的进程的进程号
4,$_
获取在此之前执行的命令或脚本的最后一个参数
2.bash shell 内置变量
常用的内置变量有echo,eval,exec,export,read,shift
2.1 echo 在屏幕上输出信息
命令格式: echo args #可以是字符串和变量的组合
功能说明:将echo后面的args 指定的字符串及变量等显示到标准输出
2.1.2 例子
[root@onetree-test001 /server/test]# echo shunmai;echo langwenke
shunmai
langwenke
[root@onetree-test001 /server/test]# echo -n shunmai;echo langwenke #<== n不换行输出
shunmailangwenke
[root@onetree-test001 /server/test]# echo "shunmai\tlangwenke\nshunmai\tlangwenke"
shunmai\tlangwenke\nshunmai\tlangwenke
[root@onetree-test001 /server/test]# echo -e "shunmai\tlangwenke\nshunmai\tlangwenke"
shunmai langwenke #加上 -e 解析 \t 空格 \n换行
shunmai langwenke
[root@onetree-test001 /server/test]# echo -e "1\b23" <== 加上-e解析以"\"开头的字符串,\b退格
2.2 eval
命令格式: eval args
功能:当shell程序执行到eval语句时,shell读入参数args,并将它们组合成一个新的命令
2.2.1 set和eval的使用
[root@onetree-test001 /server/test]# cat noeval.sh
#!/bin/bash
echo \$$#
[root@onetree-test001 /server/test]# sh noeval.sh langwenke shunmai
$2
[root@onetree-test001 /server/test]# cat noeval.sh
#!/bin/bash
eval "echo \$$# "
[root@onetree-test001 /server/test]# sh noeval.sh langwenke shunmai
shunmai
3.exec
命令格式:exec命令参数
功能:exec命令能够在不创建新的子进程的前提下,转去执行制定的命令,当指定的命令执行完毕后,该进程(也就是最初的shell)就终止了
[root@onetree-test001 /server/test]# exec date
Fri Jul 26 10:31:18 CST 2019
当使用exec打开文件后,read命令每次都会将文件指针移动到文件的下一行进行读取,直到文件末尾,利用这个实现处理文件内容
3.1例子
[root@onetree-test001 /server/test]# seq 5 > 1.log
[root@onetree-test001 /server/test]# cat exec.sh
#!/bin/bash
exec < 1.log #读取log内容
while read line #利用read一行行读取内容
do
echo $line
done
echo ok
[root@onetree-test001 /server/test]# sh exec.sh
1
2
3
4
5
ok
4. read
命令格式:read变量表名
功能:从标准串输入读取字符串等信息,传给shell程序内部定义的变量
5.shift
命令格式: shift-Shift positional parameters
功能:shift语句会按如下方式重新命名所有的位置参数变量,即$2成为$1,$3成为$2等,以此类推,在程序中每使用一次shift语句,都会使所有的位置参数依次向左移动一个位置,并使位置参数$#减1,直到减到0为止
[root@onetree-test001 /server/test]# help shift
shift: shift [n]
Shift positional parameters.
Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is
not given, it is assumed to be 1.
Exit Status:
Returns success unless N is negative or greater than $#.
shift命令的主要作用是将位置参数$1,$2等进行左移,即如果位置参数是$3,$2,$1,那么执行一次shift后,$3就变成$2,$2就变成$1,$1就消失了
5.1 例子
[root@onetree-test001 /server/test]# cat n1.sh
#!/bin/bash
echo $1,$2
if [ $# -eq 2 ]; then
shift
echo $1
fi
[root@onetree-test001 /server/test]# sh n1.sh shunmai langwenke
shunmai,langwenke
langwenke
应用场景: 当我们shell希望像命令行的命令参数通过参数控制不同的功能时,就会先传一个类似-c 的参数,然后再接内容
[root@onetree-test001 /server/test]# sh n1.sh -c shunmai
-c,shunmai
shunmai
ssh-copy-id -i /root/.ssh/id_rsa.pub
#!/bin/bash
ID_FILE="${HOME}/.ssh/id_rsa.pub"
if [ "-i" = "$1" ];then
shift
if [ -n "$2"]; then
if expr "$1" : ".*\.pub" > /dev/null ; then
ID_FILE="$!"
else
ID_FILE="$1.pub"
fi
shift
fi
6. exit
命令格式:exit-Exit the shell
功能:推出shell程序,退出之后可以有选择的,指定一个数作为返回状态
3.shell变量字串
3.1 shell变量子串介绍
3.2 shell变量子串实践
[root@onetree-test001 /server/test]# SHUNMAI="I am worker"
[root@onetree-test001 /server/test]# echo ${SHUNMAI}
I am worker
[root@onetree-test001 /server/test]# echo $SHUNMAI
I am worker
3.2.1 返回变量值长度
[root@onetree-test001 /server/test]# echo ${#SHUNMAI}
11
其他打印长度的方法
[root@onetree-test001 /server/test]# echo $SHUNMAI|wc -L
11
[root@onetree-test001 /server/test]# expr length "$SHUNMAI"
11
[root@onetree-test001 /server/test]# echo "$SHUNMAI"|awk '{print length($0)}' #利用awk的length函数计算变量长度,也可无"{$0}" 这几个字符
11
利用time命令及for循环对几种获取字符串长度方法进行比较
(1)变量自带的获取长度的方法(echo ${#char})
time for n in {1..10};do char=`seq -s "shunmai" 100`;expr length "${char}" & >/dev/null ;done
real 0m0.019s
user 0m0.007s
sys 0m0.022s
(2) 利用管道加wc的方法(echo $(char)|wc -L)
root@onetree-test001 /server/test]# time for n in {1..100};do char=`seq -s "shunmai" 100`;echo ${char}|wc -L &>/dev/null;done
real 0m0.505s
user 0m0.244s
sys 0m0.331s
(3)使用expr自带的length方法 (expr length "${char}")
[root@onetree-test001 /server/test]# time for n in {1..10};do char=`seq -s "shunmai" 100`;expr length "${char}"&>/dev/null;done
real 0m0.028s
user 0m0.019s
sys 0m0.010s
(4)利用awk自带的length的方法
[root@onetree-test001 /server/test]# time for n in {1..100};do char=`seq -s "shunmai" 100`;echo $char|awk '{print length($0)}' &>/dev/null ;done
real 0m0.364s
user 0m0.145s
sys 0m0.244s
3.2.2 截取变量的内容,从第2个字符开始截取,默认截取后面的全部字符
[root@onetree-test001 /server/test]# echo ${SHUNMAI}
I am worker
[root@onetree-test001 /server/test]# echo ${SHUNMAI:2}
am worker
3.2.3 从变量内容开头开始删除最短匹配"a*C"及"a*c"的子串
[root@onetree-test001 /server/test]# SHUNMAI=abcABC123ABCabd
[root@onetree-test001 /server/test]# echo $SHUNMAI
abcABC123ABCabd
[root@onetree-test001 /server/test]# echo ${SHUNMAI#a*C}
123ABCabd
[root@onetree-test001 /server/test]# echo ${SHUNMAI#a*c}
ABC123ABCabd
3.2.4 从变量内容开头开始删除最长匹配"a*C"及"a*c"的子串
[root@onetree-test001 /server/test]# echo ${SHUNMAI##a*c}
[root@onetree-test001 /server/test]# echo ${SHUNMAI##a*C}
abc
3.2.5 从变量内容结尾开始删除最短匹配"a*C"及"a*c"的子串
[root@onetree-test001 /server/test]# SHUNMAI=abcABC123ABCabc
[root@onetree-test001 /server/test]# echo $SHUNMAI
abcABC123ABCabc
[root@onetree-test001 /server/test]# echo ${SHUNMAI%a*C}
abcABC123ABCabc
[root@onetree-test001 /server/test]# echo ${SHUNMAI%a*c}
abcABC123ABC
3.2.6 从变量内容结尾开始删除最短匹配"a*C"及"a*c"的子串
[root@onetree-test001 /server/test]# echo ${SHUNMAI%%a*c}
[root@onetree-test001 /server/test]# echo ${SHUNMAI%%a*C}
abcABC123ABCabc
小结:
# 表示从开头删除匹配最短
## 表示从开头删除匹配最长
% 表示从结尾删除匹配最短
%% 表示从结尾删除匹配最长
3.2.7 替换字符串
[root@onetree-test001 /server/test]# SHUNMAI="I am worker,yes,worker"
[root@onetree-test001 /server/test]# echo $SHUNMAI
I am worker,yes,worker
[root@onetree-test001 /server/test]# echo ${SHUNMAI/worker/boss}
I am boss,yes,worker
[root@onetree-test001 /server/test]# echo ${SHUNMAI//worker/boss}
I am boss,yes,boss
一个/表示替换第一个字符
两个//表示替换所有字符
3.3 修改文件名
[root@onetree-test001 /server/test]# f=nis.sh
[root@onetree-test001 /server/test]# echo ${f//i/}
ns.sh
[root@onetree-test001 /server/test]# mv $f `echo ${f//i/}`
3.3.1 批量处理
[root@onetree-test001 /server/test]# for i in `ls *i*.sh`;do mv $m `echo ${m//i/}`;done
mv: missing file operand
Try 'mv --help' for more information.
mv: missing file operand
Try 'mv --help' for more information.
3.4 shell 特殊扩展变量
3.4.1 介绍
3.4.2 实践
1.${parameter:-word}功能实践
[root@onetree-test001 /server/test]# echo $test
[root@onetree-test001 /server/test]# result=${test:-UNSET} #若test没有值返回UNSET
[root@onetree-test001 /server/test]# echo $result #打印result变量,返回unset,test没有值
UNSET
[root@onetree-test001 /server/test]# echo ${test}
2.${parameter:=word}
[root@onetree-test001 /server/test]# result=${test:=UNSET}
[root@onetree-test001 /server/test]# echo $result
UNSET
[root@onetree-test001 /server/test]# echo $test
UNSET
[root@onetree-test001 /server/test]# result=${test=UNSET} #定义时忽略冒号
[root@onetree-test001 /server/test]# echo $result
UNSET
[root@onetree-test001 /server/test]# echo $test
UNSET
当变量(result)值里的变量(test)没有定义时,会给变量(result)赋值":=" 后面的内容,同时会把":="后面的内容赋值给变量(result)值里没有定义的变量(test)。
这个变量的功能可以解决变量没有定义的问题,并确保没有定义的变量始终有值
3. ${parameter:?word}
后面的parameter变量值为空或未赋值,那么word字符串将被作为标准错误输出,否则输出变量的值
[root@onetree-test001 /server/test]# echo ${key:?not defined}
-bash: key: not defined #没有定义
[root@onetree-test001 /server/test]# echo ${key?not defined}
-bash: key: not defined
[root@onetree-test001 /server/test]# key=1
[root@onetree-test001 /server/test]# echo ${key:?not defined}
1
[root@onetree-test001 /server/test]# echo ${key?not defined}
1
[root@onetree-test001 /server/test]# unset key
[root@onetree-test001 /server/test]# echo ${key?not defined}
-bash: key: not defined
本例的作用可以用于设定由于变量未定义而暴多的具体内容,如:"no defined"
4. ${parameter:+word}
${parameter:+word}的作用是:如果parameter变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值
[root@onetree-test001 /server/test]# shunmai=${langwenke:+word} #shunmai变量未定义
[root@onetree-test001 /server/test]# echo $shunmai
[root@onetree-test001 /server/test]# langwenke=20
[root@onetree-test001 /server/test]# shunmai=${langwenke:+word} #shunmai变量未定义
[root@onetree-test001 /server/test]# echo $shunmai
word
删除超过7天文件
find ${path-/data/mysql/} -name "choubao.*" -type f -mtime +7|xargs rm -rf