【汤4操作系统】深入掌握操作系统-再多看一眼就会学会的SHELL编程

SHELL脚本

SHEEL脚本主要掌握知识点

引号的区别、变量使用、系统变量/特殊变量使用、read/tput/awk、for/if/while、条件判断

输入输出重定向和管道

输出重定向

cat file #把文件内容输出到标准输出文件
cat file > newfile #输出重定向,结果等于拷贝文件
cat file >> newfile #追加file内容

#示例,按照字母顺序显示当前系统中已登录的用户
who > temp1
sort temp1 > temp2
more temp2 #逐屏显示排好序的用户名单

输入重定向

#command < filename 进程的输入来自文件filename
$cat #命令后无文件名,等待键盘输入
abcd
abcd

$cat < abc #输入文件
aaa
bbb
ccc
#将重定向文件abc输入cat进程

#标准错误输出重定向
#command 2> filename

$cat file1 file2 > file3 2> errfile

$grep string6 data_sav > count_log 2> &1
#将错误输出也输出到count_log中

image-20230614164247121

管道

管道用于连接命令,将前一个命令的标准输出重定向给后一个命令作为标准输入

command1 | command2
#对command1来说标准输出被重定向到管道,对command2来说标准输入也重定向到管道

$who | wc -l #查看系统当前有多少用户在上机使用系统

后台命令

$ls -lR > file_list &
#普通命令行的行尾加上& 就表示在后台执行

简单Shell命令

单命令执行:打印功能

#!/bin/bash
#必须指明#!/bin/bash
echo "helloworld"

多命令执行:

#!/bin/bash
  
cd /home/ty/
touch test.txt
#重定向
echo "Something" >> test.txt

Shell中的变量

常用系统变量

$HOME $PWD $SHELL $USER

 echo $HOME
/home/linux
 echo $PWD#当前路径
/home/linux/datas
 echo $SHELL
/bin/bash
 echo $USER

自定义变量

基本语法

  1. 定义变量:变量=值 等号两边不能留有空格
  2. 撤销变量:unset 变量
  3. 输出变量:echo $变量
  4. 声明静态变量: readonly 变量,注意:不能unset
A=1
echo $A
1
unset A

变量定义规则

  1. 变量名称可以由字母,数字和下划线组成,不能以数字开头,环境变量名建议大写
  2. 等号两侧不能有空格
  3. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
  4. 变量的值如果有空格,需要使用双引号或单引号括起来
D="A B C"
echo $D
A B C

可把变量提升为全局变量,可供其他shell程序使用
export 变量

特殊变量

$n

$n (描述:n为数字,$0代表脚本名称,10以内参数用$1-9 表 示 , 10 以 上 的 需 要 用 大 括 号 包 含 , 9表示,10以上的需要用大括号包含,9表示,10以上的需要用大括号包含,{10})

#!/bin/bash
echo "$0 $1 $2 $3"
12

$#

$# (功能描述:获取所有输入参数个数,常用于循环)

#!/bin/bash
echo "$0 $1 $2 $3"
echo $#

$*$@

  • $* (描述:代表命令行中所有的参数,把所有参数看成一个整体)
  • $@ (描述:也代表命令行中所有的参数,不过把每个参数区分对待)

$?

$? (描述:最后一次执行命令的状态,0:正确执行)

image-20230614165022982

单引号、双引号、反撇号、花括号

  • 单引号禁止变量替换,而双引号允许$ * 等变量替换

  • 反撇号中的字符串作为命令名

  • 花括号

  • $c="There is a teach"
    $echo "$cer reading room"
    > reading room #未定义变量cer,其值由空串替代
    $echo "${c}er reading room"
    > There is a teacher reading room #花括号将变量名和后面的字符串区分开
    

进程监控

获取进程状态信息 ps

image-20230614165650839

不带$执行时,显示活动进程的基本信息

PID:进程标识号

TTY:启动进程终端号

TIME:进程累计占用CPU时间

COMMAND:产生该进程的命令

ps -e 显示所有活动进程信息

ps -f 显示进程所有信息

image-20230614165824388

暂停进程运行:sleep命令

sleep time 进程暂停指定秒数

终止进程运行 kill

kill pid

正常结束

kill -1 pid

先挂起,终止子进程

kill -9 pid

直接杀死

read读取控制台输入

read(选项)(参数)
  • -p 指定读取值时的提示符
  • -t 指定读取值时等待的时间(秒)
$ cat read.sh
#!/bin/bash
read -t 7 -p "请输入你的名字" NAME
echo $NAME
$ bash read.sh
在7s
#!/bin/bash
echo -n "Input date with format yyyy mm dd:"
read year month day
echo "Today is $year/$month/$day,right?"
echo -n "Press any key to confirm"
read answer
echo "I know the date!"

运算符

  1. $((运算式)) $[运算式]
  2. expr +,-,\*,/,% 加减乘除取余
    expr运算符间要有空格
num=9
sum=`expr $num \* 6`
echo $sum

tput命令

image-20230614170733188

#
# program1 for tput
#
tput clear
tput cup 11 30
tput rev
echo "Hello, everybody!"
tput sgr0
tput cup 24 1
该程序先清屏, 并在屏幕中央位置(11行30列)用反极性显示
字符串“Hello, everybody!”, 恢复正常显示极性后光标停
留在屏幕左下角。

#
# program2 for tput
bell=`tput bel`
s_uline=`tput 
smul`
e_uline=`tput rmul`
tput 
clear
echo $bell $s_uline
tput cup 10 20
echo "Computer Department"
echo $e_uline
功能: 响一声铃后, 在清空的屏幕中央以下划线模式显示字
符串“Computer Department”,完成后重置正常显示模式。

条件判断

基本语法

[condition] (注意 condition前后要有空格)

常用判断条件

两个整数之间比较

符号描述
-lt(less than)小于
-le(less equal) 小于等于
-eq(equal)等于
-gt(greater than) 大于
-ge(greater equal) 大于等于
-ne(not equal) 不等于

文件权限判断

  • -r 有读的权限
  • -w 有写的权限
  • -x 有执行的权限

文件类型判断

  • -f 文件存在并且是一个常规文件
  • -e 文件存在
  • -d 文件存在并是一个目录
# 判断23是否大于2
$ [ 23 -gt 2 ]
$ echo $? #上一次执行指令的状态
0

# 判断helloworld.sh是否有写入权限
$ [ -w hellowrld.sh ]
$ echo $?
1

# 判断目录中文件是否存在
$ [ -e /home/linux/datas ]
$ echo $?
0

多条件判断

&& ||

流程控制

IF判断

#测试命令行参数是否为一个已经存在的文件或目录的用法
#!/bin/bash
if [ -f $1 ]
then    
        echo "File $1 exists"
fi      
if [ -d $HOME/$1 ]
then    
        echo "File $1 is a directory"
fi 
#!/bin/bash
if [ $1 -eq 1 ]
then
	echo "hello"
elif [ $1 -eq 2 ]
then
	echo "nihao"
fi
$ bash if.sh 2
班长真丑

test语句

test可以测试三种对象

  • 字符串
  • 整数
  • 文本

test “$answer” = “yes”

test $num -eq 18

test -d tmp

image-20230614173034274

case 语句

$ cat case.sh
#!/bin/bash
case $1 in
1)
	echo "班长"
;;
2)
	echo "学习委员"
;;
3)
	echo "体育委员"
;;
esac
$ bash case.sh 2
学习委员
if [ $# -ne 1 ]# $#获取参数个数
then
        echo "one argument must be declared"
        exit
fi
case $1 in
        file1)
                echo "User selects file1"
                ;;
        file2)
                echo "User selects file2"
                ;;
        *)
                echo "Must choose one"
                ;;
esac

for循环

for 变量名 in 单词表

do

命令表

done

语法1

$ cat for.sh
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
	s=$[$s+$i]	
done
echo $s
$ bash for.sh
5050

语法2

$ cat for2.sh
#!/bin/bash
for i in $*
do
	echo $i
done
$ bash for2.sh 1 2
1
2
#寻找指定文件或拷贝当前目录下的所有文件到backup 
if [ ! -d $HOME/backup ]
then
        mkdir $HOME/backup #不存在目录时创建
fi
flist=`ls`
for file in $flist
do
        if [ $# -eq 1 ]
        then
                if [ "$1" = "$file" ]
                then
                        echo "$file found";exit
                fi
        else
                cp $file $HOME/backup
                echo "$file copied"
        fi
done
echo "***backup completed***"

WHILE循环

while 命令或表达式

do

​ 命令表

done

$ cat while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
	s=$[$s + $i]
	i=$[$i + 1]
done
echo $s

$ bash while.sh
5050

if [ $# -eq 2 ]
then
        loop=$2
else
        loop=5
fi
i=1
while [ $i -le $loop ]
do
		#建立以file开头,变量i结束的空文件名
        >$1$i
        i=`expr $i + 1`
done

函数

系统函数

basename

basename [string / pathname] [suffix] (描述:basename命令会删掉所有的前缀包括最后一个‘/’字符,然后将字符串显示出来)
1
# 方式1
[linux@localhost datas]$ basename /home/linux/banzhang.txt
banzhang.txt

# 方式2
[linux@localhost datas]$ basename /home/linux/banzhang.txt .txt
banzhang
1234567

dirname

dirname 文件绝对路径 (描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
1
[linux@localhost datas]$ dirname /home/linux/banzhang.txt
/home/linux
12

自定义函数

  • 函数说明必须放在调用程序之前
  • 调用程序可以传递参数给函数,函数可用return将运行结果返回给调用程序

image-20230614183717258

# 格式
[ function ] funname[()]
{
	Action:
	[return int;]
}
funname
# DESC 计算输入两个参数的值
$ cat sum.sh
#!/bin/bash
function sum(){
	s=0;
	s=$[$1 + $2]
	echo $s
}
read -p "input your param1:" P1
read -p "input your param2:" P2
sum $P1 $P2
$ bash sum.sh
input your param1:1
input your param2:2
3
check_user()
{ 
        user=`who | grep $1`
        if [ -n "$user" ]
        then
                return 0
        else
                return 1
        fi
}
while true
do
        echo -n "Input username:"
        read uname
        check_user $uname
        if [ #? -eq 0 ]
        then echo "user $uname online"
        else echo "user $uname offline"
        fi
done

shell工具

cut

cut命令从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出
cut [选项参数] filename

  • -f 列号,提取第几列
  • -d 分隔符,按照指定分隔符分隔列
# DESC 切割cut.txt第一列
[linux@localhost datas]$ cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
[linux@localhost datas]$ cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le

# DESC 获取第三行第一个单词
[linux@localhost datas]$ cat cut.txt | grep guan | cut -d " " -f 1
guan
1234567891011121314151617

sed

sed是一种流编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,成为“模式空间”,接着sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,知道文件末尾,文件内容并没有改变,除非你使用重定向存储输出
sed [选项参数] ‘command’ filename

image-20230614184755750

  • -e 直接在指令列模式上进行sed的动作编辑

命令功能描述

  • a 新增
  • d 删除
  • s 查找并替换
# DESC 在第二行后增加mei nv字符
[linux@localhost datas]$ sed -e "2a mei nv" sed.txt
dong zhen
guan zhen
mei nv
wo wo
lai lai

awk

awk 一个强大文件分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理

awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename
  • -F 指定输入文件分隔符
  • -v 赋值一个用户定义变量

image-20230614185035926

image-20230614185112671

image-20230614185129415

image-20230614185328018

实验题粗略重写

(1)清屏;

(2)提示用户输入要检测其状态的文件名;

(3)显示该文件的状态信息(提示:该状态信息可由命令ls –l 来得到),或找不到该文件时的错误提示;

(4)用cut命令,或用sed或awk命令来截取状态信息中文件的大小并保存;

(5)每隔5秒钟检测一次该文件大小的信息,并与保存的文件原来的大小相比较;

(6)如果文件大小未改变,则屏幕显示不变,并继续每隔5秒钟检测一次;

(7)如果文件大小已改变,则保存新的文件大小,并在屏幕上显示:file [ filename ] size changed(括号中的filename为本程序运行时用户输入的被检测的文件名)。程序继续每隔5秒钟检测一次文件的大小;

(8)程序循环执行5~7步的操作。当被检测的文件或者已累计改变了两次大小,或者已连续被检测了十次还未改变大小时,给出相应提示,然后清屏退出。

#!/bin/bash
tput clear
read -p "Please Input the filename:"  file
echo $file
pre=`ls -l $file | awk '{print $5}' `
echo $pre
i=1
count=0
while [ $i -le 10 ]
do
        if [ $count -eq 2 ]
        then
                echo "已经改变两次"
                exit
        fi
        cur=`ls -l $file| awk '{print $5}'`
        echo "当前文件大小:$cur"
        if [ $cur -ne $pre ]
        then
                pre=$cur
                echo "file$file size changed"
                count=`expr $count + 1`
        fi
        i=`expr $i + 1`
        sleep 3
done
echo "十次未改变大小"

编写一个用户监测程序usr_monitor, 其运行格式为:

usr_monitor username

其中username是用户指定的任意一个用户名。程序运行时首先列出当前系统中的已登录用户的名单,再检查指定用户是否已登录。如果已登录,则显示相应信息;如果未登录,则等待该用户登录,直到指定用户登录进入系统为止。

#!/bin/bash
if [ $# -ne 1 ]
then
        echo "请输入用户名!!"
        exit
fi

users=`who | awk '{print $1}'`
echo $users

user_input=$1
compare=`echo "$users" | grep -w "$user_input"`
echo $compare
#-z判断字符串是否为空
while [ -z $compare  ]
do
        echo "等待用户[$user_input]..."
        sleep 3
        users=`who | awk '{print $1}'`
        compare=`echo "$users" | grep "$user_input"`
done

echo "[$user_input] 登录完成"

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值