shell编程

目录

 

1 shell中的特殊字符

1.1 通配符

1.2 管道

1.3 重定向

1.4 EOF与<<结合使用

1.5 命令置换

1.6 链接命令

1.7 环境变量 

1.8 其他命令

2 shell编程

2.1 步骤

2.2 shell变量     

2.3 位置参数变量

2.4 算数运算

2.5 test命令

2.6 整数测试

2.7 字符串 

2.7.1 字符串比较

2.7.2 字符串截取、替换和删除

2.8 条件语句(if...then...fi)

2.9 多路分支语句

2.10 循环语句

2.11 shell函数

2.12 判断文件夹或文件是否存在

2.13 获取文件内容

2.14 等待(slepp)

2.15 查看某个进程是否存在

2.16 获取某个进程的内存占用和CPC占用率

2.17 输出到文件

2.18 自增(i++)自减(i--)

2.18 数组


shell是核心程序kernel之外的指令解析器,是一个程序,同时是一种命令语言和程序设计语言。shell是命令解析器,用户输入命令,它去解析。

1 shell中的特殊字符

1.1 通配符

  1. *       用file_*.txt,匹配file_w.txt、file_l.txt;
  2. ?     用file_?.txt,匹配file_1.txt、file_2.txt、file_3.txt;<长度字符>
  3. [...]    用file_[orx].txt,匹配file_o.txt、file_r.txt、file_x.txt;
  4. [ - ]    用file_[a-z].txt,匹配file_a.txt、file_b.txt...file_z.tx;
  5. [^...]   用file_[^ort].txt,除了file_o.txt、file_r.txt、file_x.txt 的其他文件;

1.2 管道

     管道可以把一系列命令连接起来,意味着第一个命令的输出将作为第二命令的输入,通过使用“|”连成一个管道;

     comand1 | command2 //把一个命令command1执行结果作为command2的输入传给command2

ls | wc -w //查看文件的单词数
cat test.c | grep hello //输出test.c中hello
find ./ -name test -size +1k | xargs rm -rf

 

1.3 重定向

  1. command > file        把标准输出重定向到新文件中 ;ls > file,将ls的执行结果,写到file文件中,若同名文件将被删除;
  2. command >> file       ls >> file,将ls的执行结果,追加到file文件中;
  3. command < file         ls < file,将file中的内容作为输入传给命令ls;
  4. command &> flie       ls 1.c &> file,ls命令,查看一个不存在的文件时,将系统错误提示信息存在file中;
  5. command <<delimiter  从标准输入中读入,直到遇到delimiter结束(把内容当作标准输入传给程序)

1.4 EOF与<<结合使用

     EOF与 << 结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell。

#向test.txt文件存入abcdef hello word ! 文本
cat >> test.txt << EOF 

abcdef 

hello word ! 

EOF

1.5 命令置换

     命令置换:将一个命令的输出作为另一个命令的参数。

     commad1  ·commad2·    //命令comand2的输出将作为命令commad1的参数。

1.6 链接命令

ln -s 1.c link.c //软链接建立
ln 1.c lindk.c //硬链接建立

1.7 环境变量 

     1、PATH 和 HOME

echo $PATH  #输出PATH环境变量
echo $HOME  #s输出HOME环境变量

     2、给环境变量追加内容: 格式 export PATH=$PATH:(增加的内容)

     3、env 输出环境变量

env #输出所有环境变量
env $PATH #输出PATH环境变量

1.8 其他命令

       1、alias --- 取别名(相当于C++中的引用)      

alias ll=`ls -l` #ll就相当于ls -l 

      2、find用法:find + 路径 + 选项 + “查找内容”

find ./ -name "test*" //查找当前目录的test开头的文件
find ./ -nmae "[A-Z]*" //查找当前目录大写字母开头的文件
find ./ -nmae "[A-Z]*" -printf //查找当前目录大写字母开头的文件
find ./ -name "test" -tpye d//查找test目录

   -type 查找某一类型的文件,诸如:

  1. b - 块设备文件。
  2. d - 目录。
  3. c - 字符设备文件。
  4. p - 管道文件。
  5. l - 符号链接文件。
  6. f - 普通文件。
     

2 shell编程

2.1 步骤

  1. 建立shell文件<注释用#>,vi test.sh
  2. 改变shell文件的执行权限,chmod +x test.sh
  3. 执行shell文件,./test.sh

2.2 shell变量     

  • Shell变量的最基本规则:变量只有字符串和整数两种类型。在shell运算中都是整数运算或字符串操作运算。
  • 表达式运算,格式: $[表达式] 。 取值要加$赋值不要加$
  • 表达式替换形式两种:$[表达式], $((表达式 ))
  • 输出命令: echo 选项-e (常用)
  • 输入命令:read 参数的使用规则 (常用)
  • 输出命令:tee  用在管道相关的情况,调试时非常有用
#! /bin/sh
cout=1
echo $cout
echo ${cont} #和上面等价
echo $[cont] #和上面等价
name='xiaoming'
echo $name
set | grep cout #查看变量名和值,将输出num=5
  • ${variablename} 显示实时值
  • ${variablename:+value} 变量值为value
  • ${variablename:?value}  如果变量定义了则值为之前的值。否则输出报错
  • ${variablename:-value}  如果变量定义了则值为之前的值。否则值为value
  • ${variablename:=value}  如果变量定义了则值为之前的值。否则值为value
#!/bin/bash
index=8
echo ${index:+"123"}
num=11
echo ${num:?"124"}
echo ${a:-"100"}
b=22
echo ${b:="200"}
  • unset --- 取消变量
num=99
echo ${num}
unset num
echo ${num} #输出空

2.3 位置参数变量

  1.  $0         脚本名称,echo $0 将在输出该脚本文件名;
  2. $1,$2,$3...$n     第一个到第n个命令行参数名;
  3. $#          命令行参数的个数;
  4. $*          参数列表;
  5. $@        参数列表;
  6. $?          上一次执行的状态码;
  7. $$          正在执行进程的ID号;
#! /bin/sh
echo $0
echo $#
echo $@
echo $*
echo $?
echo $$

  注意:#!/bin/bash 表示根据这个得到解释器的类型,调用相对的解释器。

2.4 算数运算

      expr <加(+)、减(-)、乘(\*)、整除(\)、求模(%) >

      expr 12 + 5\*3  //27

num=9
sum=`expr $num / 6` #sum = 1
echo $sum

     let用法 

    在shell中可以使用let来指示命令是算术表达式,let表达式内变量不用加$

num=9
let sum=9/6 #或者"sum=9/6"
echo $sum

2.5 test命令

  • test语句可测试三种对象:字符串、整数、文件属性。真为0,假为1
  1. test -d name   测试name是否为一个目录;
  2. test -e name   测试一个文件是否存在;
  3. test -f name    测试那么是否为普通文件;
test -d test
echo $?   #输出结果

2.6 整数测试

  1. $a -eq $b    测试a与b是否相等真为0,假为1
  2. $a -ne $b     !=
  3. $a -gt $b      >
  4. $a -ge $b    >=
  5. $a -lt $b      <
  6. $a -le $b     <=
a=9
b=9
test $a -eq $b 
echo $?   #输出0

2.7 字符串 

2.7.1 字符串比较

  1. “=”  相等<真为0,假为1>
  2. “!=”不等;
  3. “- n” 判断是否为空;
  4. “- z” 长度为0;
  5. “\>”、“\<”  大于小于;
#!/bin/sh
str1="xiaoming"
str2="xiaohong"
if [ $str1 = $str2 ] #[等价] if [ "$str1"="$str2" ]两边要有空格,
then echo "="
else echo "!="
fi

if [ ${str1}\>${str2} ] #等价 if test $str1\>$str2
then echo ">"
else echo "<"
fi

if [ -n $str1 ]
then echo "1111"
else echo "0000"
fi

if [ -z $str1i ]
then echo "2222"
else echo "0000"
fi 

2.7.2 字符串截取、替换和删除

  1. 截取   :
  2. 替换   /
  3. 删除左边  #
  4. 删除右边  %

例:dome="wang.csdn.net"

  1. ${demo:2:3}  #从第2字符开始取3个字符,ng.c
  2. ${demo:2}  #从第0字符开始取2个字符,wa
  3. ${demo:0-3}  #取倒数2个字符,net
  4. ${demo/wang/good} #将wang替换为good
  5. ${demo/./-} #替换第一个点(".")-首次匹配,wang-csdn.net
  6. ${demo//./-} #贪婪模式,替换所有点("."),wang-csdn-net
  7. ${demo#*.} #从左删除首次匹配部分.的左边所有内容包括.,csdn.net
  8. ${demo##*.} #贪婪模式,从左删除所有匹配部分,net
  9. ${demo%.*} #从右边删除首次匹配的部分.*,wang.csdn
  10. ${demo%%.*} #贪婪模式,从右删除所有匹配部分.*,wang

2.8 条件语句(if...then...fi)

    格式:  

1、if [ 表达式 ] //[]两边有空格
2、if test 表达式1 选项 表达式2
3、if test 选项 表达式

     1、if...then...fi

          if  表达式

              then 命令表

          fi

     2、if...then...else...fi

          if  表达式

          then  命令表1

          else  命令表2

          fi  

    3、if...then...elif then...esle...fi

  • 例1:比较两个数是否相等
a=9
b=8
if test $a -eq $b
then echo $a
else echo $b
fi
  • 例2:查看某个文件是否存在 
#! /bin/sh
FILENAME="/usr/test1.txt"
if [ -f $FILENAME ]
	then echo "yes"
	else echo "NO"
fi
  • 例3:查看多个文件是否存在 
#! /bin/bash
OBJPATH="root/domo";
TEST="test.txt";
INFO="info.txt";
if [ -f "$OBJPATH/$TEST" -a -f "$OBJPATH/$INFO" ]
then
	echo "file all exist"
else
	echo "file no exist"
fi
  •  例4:
#!/bin/bash

count=3
num=4
if [[ $count == 0 ]] && [[ $num == 0 ]];then
	echo "[1].count=$count,num=$num"
elif [[ $count == 2 ]] && [[ $num == 2 ]];then
	echo "[2].count=$count,num=$num" 
elif [[ $count > 3 ]] && [[ $num > 3 ]];then
	echo "[4].count=$count,num=$num" 
else
	echo "[5].count=$count,num=$num" 
fi

2.9 多路分支语句

     case  $_  in

              模式1)

                        命令表1

                        ;;

              

              模式2)

                        命令表2

                        ;;

              模式n)

                        命令表 n

                        ;;

    esac

a=2
case $a in
	1)
	echo xiaoming
	;;
	2|8)#2或8
	echo xiaohong
	;;
esac
#!/bin/sh
char='b'
case $char in
	a)
	echo xiaoming
	;;
	b|B)
	echo xiaohong
	;;
esac

2.10 循环语句

   1、for循环

   for...do...done

  for  变量名  in 单词表

  do

       命令表

  done

for num in 1 2 3 4 5
    do
        echo "hello $num"
    done
//打印出
hello 1
hello 2
hello 3
hello 4
hello 5

for((num=1;num<=5;num++))
	do
	  echo "hello $num"
	done

  2、while循环

    while...do...done

    while 命令式表达式

    do

          命令表

    done

num=1
while test $num -lt 5
do
    echo "num=$num"
    num=`expr $num + 1`
done
read num #相当于C中scanf
while test $num -lt 5
do
    echo "num=$num"
    num=`expr $num + 1`
done
while((num<=5))
do
    echo "num=$num"
    num=`expr $num + 1`
done

死循环

##方法1:

while :
do
    #内容
done

##方法2:
while true
do
    #内容
done

 (十)break 和 continue

for num in 1 2 3 4 5
    do
        if test $num -eq 2
        then break
        fi
        echo "hello $num"
    done

2.11 shell函数

   函数名称在当前脚本必须唯一,如果存在相同名称的函数,以最后一个为准。

    函数的创建方法一:

function 函数名称 {
    命令
}

  函数的创建方法二:

函数名称() {
    命令
}

  函数的调用方法:

函数名称 参数1 参数2 ...

  调用函数时可以传递参数,函数中使用$1、$2......来引用传递的参数。

function fun()
{
    echo "hello word!"
}
fun
function fun()
{
    echo "hello word!"
    echo $1
}
fun 12
function fun()
{
    echo "hello word!"
    return 43
    echo $1
}
fun 12
echo $?

2.12 判断文件夹或文件是否存在

-e 判断对象是否存在

-d 判断对象是否存在,并且为目录

-f 判断对象是否存在,并且为常规文件

-L 判断对象是否存在,并且为符号链接

-h 判断对象是否存在,并且为软链接

-s 判断对象是否存在,并且长度不为0

-r 判断对象是否存在,并且可读

-w 判断对象是否存在,并且可写

-x 判断对象是否存在,并且可执行

-O 判断对象是否存在,并且属于当前用户

-G 判断对象是否存在,并且属于当前用户组

-nt 判断file1是否比file2新  [ "/data/file1" -nt "/data/file2" ]

-ot 判断file1是否比file2旧  [ "/data/file1" -ot "/data/file2" ]

  • 查看某个文件是否存在 
#! /bin/sh
FILENAME="/usr/test1.txt"
if [ -f $FILENAME ]
	then echo "yes"
	else echo "NO"
fi
  •  查看文件是否存在 
#! /bin/sh
FILENAME="/usr/test1.txt"
if [ ! -f $FILENAME ]
	then echo "NO"
	else echo "YES"
fi
  • 查看多个文件是否存在 
#! /bin/bash
OBJPATH="root/domo";
TEST="test.txt";
INFO="info.txt";
if [ -f "$OBJPATH/$TEST" -a -f "$OBJPATH/$INFO" ]
then
	echo "file all exist"
else
	echo "file no exist"
fi
  • 查看文件夹是否存在
#! /bin/bash
OBJPATH="root/domo";
if [ -d "$OBJPATH" ]
then
	echo "file all exist"
else
	echo "file no exist"
fi

2.13 获取文件内容

方法一:

#! /bin/bash
fileName="/root/dome/test.txt"
while read line
do
	echo $line
done < $fileName

方法二:

#! /bin/bash
fileName="/root/dome/test.txt"
cat $fileName | while read line
do
	echo $line
done

2.14 等待(slepp)

sleep 10       #休眠10s(可用小数)
usleep 1000    #休眠1000毫秒

2.15 查看某个进程是否存在

   查看某个进度是否存在,不存在则拉起(相当于守护进程)

#!/bin/bash

DIR=/root/work/demo
NAME=test	#可执行文件
while :
do
	count=`ps -ef | grep $NAME | grep -v "grep" | wc -l`
	echo $count
	if [[ $count == 0 ]];then
		${DIR}/${NAME}
	else
		sleep 5
	fi
done

命令:"ps -ef | grep test | grep -v grep | wc -l",各子命令其作用如下

  • ps -ef 指令用来查询所有进程;"-e" 参数代表显示所有进程,"-f" 参数代表全格式;
  • grep test 通过管道来过滤指定 test进程;
  • grep -v 是反向查询的意思,即过滤出不包含 -v 参数后指定字符的信息;
  • grep -v grep 的作用是即反向过滤除结果集中包含 grep 的项;grep test这个命令过滤进程,该命令本身执行的时候也是一个进程,并也带有 test 关键字,会出现在最后输出的进程信息里;所以需要 -v grep 过滤;
  • wc -l 是统计结果的行数。

2.16 获取某个进程的内存占用和CPC占用率

#!/bin/bash
pid=` ps -A | grep$1 | grep -v grep | awk '{print $2}' `  #$1是脚本的参数(进程名) 
echo $pid 
while true
do
    echo -en "`date'+%Y-%m-%d %H:%M:%S'`" >>$1_memlog.txt                  #时间
    echo -en "\t`cat/proc/$pid/status|grep -e VmRSS`" >> $1_memlog.txt  #获取内存占用
    echo -en "\t\t`ps -eo comm,pcpu |grep $1`\r\n" >> $1_memlog.txt       #CPU占用率 
    sleep 1
done

命令解析 

   (1) date '+%Y-%m-%d %H:%M:%S'【获取系统时间】

   (2) ps -A | grep $1 | grep -v grep | awk awk '{print $2}'  【获取进程号】

  •  ps -A  指令用来查询所有进程
  • grep $1 通过管道来过滤指定进程,$1是脚本的参数即进程名;
  • grep -v 是反向查询的意思,即过滤出不包含 -v 参数后指定字符的信息;
  • grep -v grep 的作用是即反向过滤除结果集中包含 grep 的项;grep $1这个命令过滤进程,该命令本身执行的时候也是一个进程,并也带有 $1 关键字,会出现在最后输出的进程信息里;所以需要 -v grep 过滤;
  • awk '{print $2}' 输出每行的2列内容,注意:这里要根据实际情况更改,不同系统的列不同

   (3) cat /proc/$pid/status|grep -e VmRSS  【输出某进程的内存占用大小】

  • /proc/$pid/status 在Linux中,用户进程在/proc/{pid}/status文件中记录了该进程的内存使用实时情况。
    1. VmSize:虚拟内存大小;整个进程使用虚拟内存大小,是VmLib, VmExe, VmData, 和 VmStk的总和。
    2. VmLck:虚拟内存锁;进程当前使用的并且加锁的虚拟内存总数。
    3. VmRSS:虚拟内存驻留集合大小;这是驻留在物理内存的一部分,它没有交换到硬盘。它包括代码,数据和栈。
    4. VmData:虚拟内存数据;堆使用的虚拟内存。
    5. VmStk:虚拟内存栈;栈使用的虚拟内存。
    6. VmExe:可执行的虚拟内存;可执行的和静态链接库所使用的虚拟内存;
    7. VmLib:虚拟内存库; 

 (4) ps -eocomm,pcpu  【显示所有命令占用的cpu的大小】

2.17 输出到文件

1、输出时间

#!/bin/bash
LOGPATH=/root/work/demo/test.log
count=3
while true
do
  time=$(date "+%Y-%m-%d %H:%M:%S.%N")
  echo "[$time] count = $count">> $LOGPATH
  sleep 1
done

#[2023-01-02 20:14:14.376715912] count = 3
#[2023-01-02 20:14:15.378973923] count = 3
#[2023-01-02 20:14:16.381747673] count = 3
#[2023-01-02 20:14:17.384710116] count = 3
#[2023-01-02 20:14:18.386843804] count = 3

2、输出进程号

#!/bin/bash
LOGPATH=/root/work/demo/test.log
APP=test_wl	#进程名
while true
do
  ############方法一##############
  time=$(date "+%Y-%m-%d %H:%M:%S.%N")
  echo "[$time] APP pid:$(pidof $APP)">> $LOGPATH #若有多个进程,会输出所有进程号

 ############方法二##############
  pidArray=`ps -A | grep $APP | grep -v grep | awk '{print $1}'` #若有多个进程,pidArray相当于数组
  #pidList=(${pidArray})  #有些系统需要强转
  time=$(date "+%Y-%m-%d %H:%M:%S.%N")
  echo "[$time] APP pid:$pidArray">> $LOGPATH
  sleep 1
done

2.18 自增(i++)自减(i--)

#!/bin/bash
i=0
#方式一:
i=$(($i+1))
echo "1. i = $i"

#方式二:
i=$[$i+1]
echo "2. i = $i"

#方式三:
i=`expr $i + 1`
echo "3. i = $i"

#方式四:
let i++
echo "4. i = $i"

#方式五:
let i+=1
echo "5. i = $i"

#i--,把+改-

2.18 数组

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值