【linux】编写linux脚本

1、linux shell种类

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

其中/bin/bash是免费的所以用的最多,一般情况不区分 Bourne Shell 和 Bourne Again Shell

2、shell脚本

首先脚本如果是用的shell写的,后缀就是.sh,如果是php写的,就是.php,
然后执行之前要赋予执行的权限,最后用/bin/sh 文件名就好了(最好还是用/bin/bash 使用过程发现数组声明用/bin/sh会报错)

touch test.sh
chmod +x ./test.sh //注意这里要写明路径,不然就会去默认的path路径里找文件了
/bin/sh test.sh
或者 ./test.sh

3、编写shell脚本

3.1、shell变量

局部变量和全局变量

printenv 或者 echo $变量名 :查看全局变量的命令
set :查看局部变量的命令

变量名=变量值:声明局部变量
export 变量名:将局部变量变为全局变量,注意:这里没有$
unset $环境变量名 :删除环境变量名

声明的环境变量可以在子进程中使用,但是子进程声明的全局环境变量是不能影响到父进程的。

变量声明和赋值

name="wcy" //名字可以加_,但是不能用bash的关键字
echo $name                    #单引号就是原样输出,即输出$name,如果是要输出命令结果,可以用 $(命令) 或者 ``
name="123"
echo "my name is ${name}"     #加不加{}其实都可以,方便识别的
for file in $(ls -l); do      #shell命令加 $()
        echo $file
done
readonly name
echo name
unset name //删除变量

#字符串
str='my name is wcy'          #单引号只能原样输出
str="my name is \"${name}\" !\n"  #双引号可以输出变量,转义字符逻辑和Java一样
echo ${#str}                  #输出字符串长度 
echo ${str:1:4}               #输出字符串1-4位 和java逻辑一样

#数组
num=(1 2 3 4)                  #数组比较特别,用(),隔开是用的空格
valuen=${num[1]}
valuen=${num[@]}              #获取数组所有元素
valuen=${num[*]}              #获取数组所有元素
len=${#num[1]}                #获取第一个元素长度
len=${#num[@]}                #获取数组长度

# #注释单行

:<<!
批量注释,这个!可以换成其他符号
!

#参数扩展
${parameter:-word}
    paramter存在,就是原值,否则就是word
${parameter:+word}
    paramater存在,就会执行paramter word命令,否则就执行pamater命令

3.2、传递参数和运算符

脚本内传参

./temp.sh 1 2 : 这就相当于传递了两个参数
$0:  默认为执行的文件名,包括路径
$?:     这个是退出状态码,0代表正常结束
$#:    参数个数
$*:  所以参数以"$1 $2 … $n"的形式输出
$@:所有的参数以"$1" "$2" … "$n"形式输出 

运算符

除了正常的+、-、*、/、%、=、、!=、==

注意:
1、数学表达式的计算需要使用 `expr 1 + 1` (注意这里是反引号,并且需要有空格) 命令或者 $[1 + 1] 这样的格式 
2、*需要转义 变成\*才能用

还有
-eq:判断等于
-ne:判断不等于
-gt:大于
-ge:大于等于
-lt:小于
-le:小于等于

逻辑运算符:&& ||
与或非:-a、-o、!

字符串运算符

= :检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=:检测两个字符串是否不相等,不相等返回 true。[ $a != $b ] 返回 true。
-z: 检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n:检测字符串长度是否不为 0,不为 0 返回 true。[ -n "$a" ] 返回 true。
$:检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

文件测试运算符


-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。

输出重定向:

其实就三个:
<    从文件输入
>    从文件输出
<<  内联输出重定向,简单的来说就是指定一个标记来直接打印输出

例子

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

就和上面的数字运算符等等就可以搭配使用了

num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

或者不声明test 通过下面这样的方式,注意前方括号后面、后方括号前面都有空格

if [ 1 -lt 2 ]
then
    echo 
else
    echo 
fi

复合条件:

[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]

3.3、结构化命令

if-else

# 这里的if判断结果和java一样是true、false,如果后面接的是一个命令,是依据状态码的,如果返回是0,就是true,否则就是false
if command
then
      commands
fi

或者
if command; then
      commands
fi

# 还有就是
if command
then
      commands
else
      commands 
fi

# 这里有个小技巧,就是上面这个结构语句的简写方式
if [ -z ""]
then 
    echo 0
else
    echo 1
fi
可以写成下面这样:
[ -z "" ] && echo 0 || echo 1

if - then 高级用法:

1、(( expression )):支持test使用的标准数学运算符之外还有 ++、--、!、~、**、&、&&、|、||、<< 等,建议使用这个

2、[[ expression ]]  :这个功能在于可以使用模式匹配,例如 if [[ $user == r*]]

循环

# for循环
for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
# while 
while condition
do
    command
done
# until 
until condition
do
    command
done
# case...esac
case 值 in
模式1)
    command1
    command2
    ...
    commandN
    break     #和java一样
    ;;
模式2)
    command1
    command2
    ...
    commandN
    continue  #和java一样
    ;;
esac
# 包含脚本
. filename   # 注意点号(.)和文件名中间有一空格

或

source filename

被包含文件不需要显式的赋予可执行权限

4、写一个实用的脚本

#/bin/bash
#environment variable
source /etc/profile
#cpu
cpu_us=`vmstat | awk '{print $13}' | sed -n '$p'`
cpu_sy=`vmstat | awk '{print $14}' | sed -n '$p'`
cpu_id=`vmstat | awk '{print $15}' | sed -n '$p'`
cpu_sum=$(($cpu_us+$cpu_sy))
if(($cpu_sum >= 90))
        then
        msg="TIME:$(date +%F_%T)
                 HOSTNAME:$(hostname)
                 IPADDR:$(ifconfig |awk 'NR==2{print $2}')
                 MSG:CPU使用率过高!已经用了${cpu_sum}%"
            echo $msg
        vmstat | awk '{print $1,$13,$14,$15}' | sed -n '2,$p' > /test/tt.txt
        /test/sendmail.py $msg
fi
posted @ 2022-07-25 20:07  吴承勇  阅读(2845)  评论(0编辑  收藏  举报