shell笔记-全面总结-强化脚本编写能力

最近给双十一晚会做直播,并且双十一红包一角标广告形式投放出去,在预热阶段需要看下效果,数据团队没法给出一些指标数据,需要我们自己做数据分析给出,平时shell使用的少,很多数据分析的命令忘记了,趁此机会总结下:

shell文件头

需要定义解释器
#!/bin/bash

执行方式
第一种,作为程序执行:
chmod +x ./red-data.sh #给脚本添加执行权限
./ red-data.sh #执行脚本
第二种,作为解释器参数执行:
/bin/sh   red-data.sh

变量

定义
shell中没有变量类型的概念,并且不需要提前声明,赋值=号左右不能有空格,如:
variableName="value"
如果shell中没有给变量赋值,则默认是空
调用变量
只需要在变量名字前加$即可调用,但是有时候为限定变量名的边界,需要大括号{}
site="youku"
echo $site
echo ${site}is playing video
设置只读变量
site="youku"
readonly site
myUrl="tudou"

[[email protected]]$ site="tudou"
-bash: site: readonly variable
删除变量
使用unset删除变量,但是不能删除只读变量:
unset variable_name
特殊变量、参数
$0  shell中在$0中存放了脚本本身的名字,
$? 是显示最后命令的退出状态, 0 表示没有错误,其他表示有错误
$!  shell把最后一个发送到后台进程的id
$$  登录shell的进程id
$#   存放命令行中输入参数的个数,通常用来校验输入参数是否正确使用
$*   传递给程序的所有参数,在参数个数不确定时候,很有用
${n} 如果传递9个以上参数,不能用$10、$11来去参数,必须使用${10}、${11}
$@  用法,$@要使用双引号括起来,否则和$*的用法相同了:
变量替换
${parameter:-value}   是如果parameter不为空就替换为它的值,为空就替换为value
${parameter:=value}  是parameter为空时,不但使用value,而且把它赋值给parameter(注意=),这种方法 不能给位置参数赋值,parameter不能是数字
${parameter:?value}  是parameter不为空,shell就替换它的值,否则shell把value写入标准错误,然后退出(这种情况发生在登录shell中,不会冲系统注销)
${parameter:+value}   是如果parameter不为空就替换为value,否则什么也不替换

引用

单引号
单引号忽略所有特殊符号
双引号
部分特殊符号不被忽略
A)美元符号
B)反引号
B)反斜杠
双引号中用反斜杠去掉字符的特殊意义(美元符号、反斜杠、反引号、换行符、其它双引号),但是反斜杠在其它特殊符号前,双引号要把它忽略。
15:03 [[email protected]]$ echo "\   hello world  \$y and \"$x\""
\   hello world  $y and ""
第一个空格前的反斜杠没有被忽略,显示出来
反斜杠
续行、转义
反引号
告诉shell执行括起来的命令
$(...)结构
格式:$(command) 和反引号功能一样
14:59 [[email protected]]$ echo "there are $(who | wc -l) user login in"
there are 3 user login in
expr命令
expr只是整数计算,如果浮点型的计算,可以使用awk或bc计算
此命令支持的操作符有加(+)、减(-)、乘(*)、除(/)、求模(%),其中乘法*需要用反斜杠,因为linux中*会解析为当前目录下所有文件的名字

运算

算数运算
运算符 说明 举例
+ 加法 `expr $a + $b` 结果为 30。
- 减法 `expr $a - $b` 结果为 10。
* 乘法 `expr $a \* $b` 结果为  200。
/ 除法 `expr $b / $a` 结果为 2。
% 取余 `expr $b % $a` 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。
注意:乘法运算需要加反斜杠

关系运算
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
关系运算符列表
运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。
-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。

布尔运算
运算符 说明 举例
! 非运算,表达式为 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。

字符串运算
运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。
str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

文件运算
用于检测Unix文件的各种属性
操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -b $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 ... fi 语句;
if ... else ... fi 语句;
if ... elif ... else ... fi 语句。
例如:
#!/bin/bash
echo "开始处理点播散投-----------"
if [ -n "$1" ]
then
    dt=$1
else
    dt=`date -d "1 day ago" "+%Y%m%d"`
fi
echo "正在查询日期:"${dt}

注意:[ expression ] expression与[]之间一定要有空格,否则语法错误

if ... else 语句也经常与 test 命令结合使用
#!/bin/bash
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo ‘The two numbers are equal!‘
    else
    echo ‘The two numbers are not equal!
fi 
执行:
15:20 [[email protected]]$ sh test.sh
‘The two numbers are equal!‘

for循环
格式一:
for i  in  1  2  3
do
     echo  $i
done
列出当前目录下所有文件
for  file  in *
do
     echo $file
done
格式二:
不带参数的for循环,这种特殊格式,shell自动将命令行的所有参数注册列表
for var
do
     command
     ......
done
相当于
for  var  in  “$@”
do
     command
     ......
done

while循环
只要while循环后的命令状态为0,循环就会一直执行下去
格式:
while  command1
     do
           command
           command
          ...
 done

util命令
与while不同的是,只有util后的命令状态不为0,就会一直执行下去
格式:
util     commond1
     do     
          command
          ......
done

case逻辑
case可以将一个值与多个值比较
格式:
case value in
part1)  command
           ......
           command;;
........
partn)  command
           ......
           command;;
esac

把value依次与part1.....partn比较,发现匹配,则执行匹配项和双分号之间的所有命令,没有匹配则不执行。
例如:
#!/bin/bash

if [  "$#" -ne 1 ]
then
        echo "用法:number数字"
        exit 1
fi
case "$1"
     in
        0) echo zero;;
        1) echo one;;
        2) echo two;;
        3) echo three;;
        4) echo four;;
        5) echo five;;
esac

case中还支持正则表达式匹配,例如万能匹配*
#!/bin/bash

if [  "$#" -ne 1 ]
then
        echo "用法:number数字"
        exit 1
fi

case "$1"
     in
        0) echo zero;;
        1) echo one;;
        2) echo two;;
        3) echo three;;
        4) echo four;;
        5) echo five;;
        *) echo "any thing"
esac

case的匹配条件可以使用  |  逻辑或
例如:
#!/bin/bash
if [  "$#" -eq 0  -o "$#" -gt 1  ]
then
        hour=$(date +%H)
else
        hour="$1"
fi

case $hour
     in
        0? | 1[01] ) echo "Good morning";;
        1[2-7]     ) echo "Good afternoon";;
        *          ) echo "Good evening";;
esac

break、continue
break和所有程序的意思是一样的,跳出所有循环,但break后边可以跟数字参数,标示跳出第几层循环,默认不写表示跳出本层循环
如:
break n
表示跳出第 n 层循环
#!/bin/bash
for var1 in 1 2 3
do
   for var2 in 0 5
   do
      if [ $var1 -eq 2 -a $var2 -eq 0 ]
      then
          break 2
      else
          echo "$var1 $var2"
      fi
   done
done
执行结果:
15:42 [[email protected]]$ sh test-break.sh
1 0
1 5
continue 后面也可以跟一个数字,表示跳出第几层循环

字符串

拼接
shell中字符串拼接异常的简单,直接放到一起即可,如:
15:50 [[email protected]]$ echo "welcome to "$site
welcome to youku
获取长度
15:58 [[email protected]]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
15:58 [[email protected]]$ echo ${#site}
5
截取
16:00 [[email protected]]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
16:01 [[email protected]]$ echo ${site:1:3}
ouk
截取第1-3个字符

数组

shell中支持一维数组,使用和程序语言是一样的,下标也是从0开始计算index
定义格式:
空格分开
array_name=(value0 value1 value2 value3)
换行
array_name=(
value0
value1
value2
value3
)
也可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

读取
valuen=${array_name[2]}
使用@ 或 * 可以获取数组中的所有元素,例如:
${array_name[*]}
${array_name[@]}

获取长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

注释

单行注释
使用# 注释

多行注释
方法一
: '
被注释的多行内容
'
方法二
:<
被注释的多行内容
eof
 方法三
:<
被注释的多行内容
!
 方法四
 if false ; then
    被注释的多行内容
 fi

你可能感兴趣的:(架构,linux/shell)