您的位置:首页 > 运维架构 > Shell

Linux Shell脚本学习 笔记整理

2017-04-03 11:16 489 查看

指定脚本解释器

#!/bin/bash


注意:
1、该声明只能放在脚本的首行,说明该脚本使用bash解释器来解释执行,否则会被当成注释
2、bash必须使用绝对路径

3、该声明只在脚本作为可执行程序,通过./test.sh调用是才有效,如果通过sh test.sh 则会直接运行sh解释器 test.sh只是作为参数传递而已

调试脚本

通过参数-x来调试脚本 
sh -x test.sh


这将执行该脚本并显示所有变量的值。 

shell还有一个不需要执行脚本只是检查语法的模式。可以这样使用: 
sh -n test,sh


这将返回所有语法错误

shell变量

1、readonly设置只读变量
#!/bin/bash

name="Jack"
readonly name
name="Jams"
readonly修饰后,name的值不能再改变,否则执行会报错:
name: readonly variable

2、unset 删除变量
相当于将变量置为空,unset不可以删除只读变量

3、变量类型
运行shell时,会同时存在三种变量:

1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

4、特殊变量
$0 当前脚本的文件名

$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。

$# 传递给脚本或函数的参数个数。

$* 传递给脚本或函数的所有参数。

$@ 传递给脚本或函数的所有参数。

$? 上个命令的退出状态,或函数的返回值。

$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。

但是当它们被双引号(" ")包含时,

"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;

"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

单引号与双引号

单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外,但是字符串中不能再出现单引号。
双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:

$加变量名可以取变量的值

反引号仍表示命令替换

\$表示$的字面值

\`表示`的字面值

\"表示"的字面值

\\表示\的字面值

除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值。

算数运算

下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符说明举例
+加法`expr $a + $b` 结果为 30。
-减法`expr $a - $b` 结果为 -10。
*乘法`expr $a \* $b` 结果为  200。
/除法`expr $b / $a` 结果为 2。
%取余`expr $b % $a` 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。

完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

乘法符号需要转义

除了expr,还可以用(())来表示,例如:var=$(( 20 + 5 ))

数字的关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符说明举例
-eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 false。
-ne检测两个数是否相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。

布尔/逻辑运算

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。
以下介绍 Shell 的逻辑运算符(注意用了双中括号),假定变量 a 为 10,变量 b 为 20:
运算符说明举例
&&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false
||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true

字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否为0,不为0返回 true。[ -n $a ] 返回 true。
str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。
字符串比较的> < 要转义,否则会被当作重定向符号

字符串处理

取长度
str="abcd"
expr length $str   # 4
echo ${#str}       # 4


查找子串的位置

str="abc"
expr index $str "a"  # 1
expr index $str "b"  # 2
expr index $str "x"  # 0
expr index $str ""   # 0


截取子串
str="abcdef"
expr substr "$str" 1 3  # 从第一个位置开始取3个字符, abc
expr substr "$str" 2 5  # 从第二个位置开始取5个字符, bcdef
expr substr "$str" 4 5  # 从第四个位置开始取5个字符, def

echo ${str:2}           # 从第二个位置开始提取字符串, bcdef
echo ${str:2:3}         # 从第二个位置开始提取3个字符, bcd
echo ${str:(-6):5}        # 从倒数第二个位置向左提取字符串, abcde
echo ${str:(-4):3}      # 从倒数第二个位置向左提取6个字符, cde

str="abbc,def,ghi,abcjkl"
echo ${str#a*c}     # 输出,def,ghi,abcjkl  一个井号(#) 表示从左边截取掉最短的匹配 (这里把abbc字串去掉)
echo ${str##a*c}    # 输出jkl,             两个井号(##) 表示从左边截取掉最长的匹配 (这里把abbc,def,ghi,abc字串去掉)
echo ${str#"a*c"}   # 输出abbc,def,ghi,abcjkl 因为str中没有"a*c"子串
echo ${str##"a*c"}  # 输出abbc,def,ghi,abcjkl 同理
echo ${str#*a*c*}   # 空
echo ${str##*a*c*}  # 空
echo ${str#d*f)     # 输出abbc,def,ghi,abcjkl,
echo ${str#*d*f}    # 输出,ghi,abcjkl

echo ${str%a*l}     # abbc,def,ghi  一个百分号(%)表示从右边截取最短的匹配
echo ${str%%b*l}    # a             两个百分号表示(%%)表示从右边截取最长的匹配
echo ${str%a*c}     # abbc,def,ghi,abcjkl


字符串替换
str="apple, tree, apple tree"
echo ${str/apple/APPLE}   # 替换第一次出现的apple
echo ${str//apple/APPLE}  # 替换所有apple

echo ${str/#apple/APPLE}  # 如果字符串str以apple开头,则用APPLE替换它
echo ${str/%apple/APPLE}  # 如果字符串str以apple结尾,则用APPLE替换它


大小写转换
##转为大写
echo $PATH | tr '[a-z]' '[A-Z]'
##转为小写
echo $PATH | tr '[A-Z]' '[a-z]'


文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

属性检测描述如下:
操作符说明举例
-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。
-c file检测文件是否是字符设备文件,如果是,则返回 true。[ -c $file ] 返回 false。
-d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。
-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。
-p file检测文件是否是有名管道,如果是,则返回 true。[ -p $file ] 返回 false。
-u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。
-r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。
-w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。
-x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。
-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

流程控制

if语句

if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi


注意是elif不是elseif

for循环

for loop in `seq 10`
do
echo "$loop"
done


循环支持break和continue

while循环

int=1
while [ $int -lt 5 ]
do
echo $int
let "int++"
done


循环支持break和continue

switch/case语句

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1)  echo '你选择了 1'
;;
2)  echo '你选择了 2'
;;
3)  echo '你选择了 3'
;;
4)  echo '你选择了 4'
;;
*)  echo '你没有输入 1 到 4 之间的数字'
;;
esac


;; 相当于break

获取用户控制台输入

read -p (提示语句)  -t(等待时间) -n(字符个数) -s(不回显)  readvalue

read命令提供了-p参数,允许在read命令行中直接指定一个提示
-t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态
-n选项设置read命令计数输入的字符。当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量
-s选项能够使read命令中输入的数据不显示在监视器上(实际上,数据是显示的,只是read命令将文本颜色设置成与背景相同的颜色)

在read命令行中也可以不指定变量.如果不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

echo颜色设置

#colour level
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

#定义记录日志的函数
log_info()
{
time=`date "+%D %T"`
echo "[$time] : INFO    : $*"
$SETCOLOR_NORMAL
}

log_warn()
{
time=`date "+%D %T"`
$SETCOLOR_WARNING
echo "[$time] : WARN    : $*"
$SETCOLOR_NORMAL
}

log_succ()
{
time=`date "+%D %T"`
$SETCOLOR_SUCCESS
echo "[$time] : SUCCESS : $*"
$SETCOLOR_NORMAL
}

log_error()
{
time=`date "+%D %T"`
$SETCOLOR_FAILURE
echo "[$time] : ERROR   : $*"
$SETCOLOR_NORMAL
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: