文章目录
shell概述
shell是一个命令行解释器,翻译官的作用
硬件–Linux内核–hell–层应用程序
可以进行复杂的流程控制,脚本编写
shell还是一个功能强大的编程语言,易编写,易调试,灵活性强。
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@localhost ~]# ll /bin/ | grep bash
-rwxr-xr-x. 1 root root 964536 3月 31 2020 bash
lrwxrwxrwx. 1 root root 10 7月 18 19:03 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root 6964 3月 31 2020 bashbug-64
lrwxrwxrwx. 1 root root 4 7月 18 19:03 sh -> bash
[root@localhost ~]# echo $SHELL
/bin/bash
shell脚本入门
脚本格式
#!/bin/bash 指定解析器
sh是bash的软链接,效果一样
[root@localhost shell]# touch hello.sh
[root@localhost shell]# vim hello.sh
#!/bin/bash
echo "hello world"
用bash的方法执行
[root@localhost shell]# bash ./hello.sh
hello world
直接执行
[root@localhost shell]# ./hello.sh
-bash: ./hello.sh: 权限不够
[root@localhost shell]# ll
总用量 4
-rw-r--r--. 1 root root 31 8月 16 00:20 hello.sh
[root@localhost shell]# chmod +x hello.sh
[root@localhost shell]# ll
总用量 4
-rwxr-xr-x. 1 root root 31 8月 16 00:20 hello.sh
[root@localhost shell]# ./hello.sh
hello world
用一个点或者source的方法执行(这种方法不启动子shell进程)
[root@localhost shell]# source hello.sh
hello world
[root@localhost shell]# . hello.sh
hello world
[root@localhost shell]# type source
source 是 shell 内嵌
变量
分类:
系统预定义变量,自定义变量
全局变量,局部变量
系统预定义变量
常用系统变量:&HOME, P W D , PWD, PWD,SHELL,$USER
[root@localhost shell]# echo $HOME
/root
[root@localhost shell]# env 查看全局变量
[root@localhost shell]# printenv
set 查看当前bash中所有的变量
自定义变量
基本语法
- 定义变量:变量名=变量值
- 撤销变量:unset 变量名
- 声明静态变量:readonly 变量名,不能unset
规则
- 变量名称由字母数字下划线组成,不能以数字开头,环境变量名建议大写
- 等号俩测不能有空格
- 在bash中,默认字符串类型,不能直接运算
- 变量值如果有空格,需要使用单引号或者双引号括起来
[root@localhost shell]# a=2
[root@localhost shell]# echo $a
2
[root@localhost shell]# my_var=2
[root@localhost shell]# echo my_var
my_var
[root@localhost shell]# b='hello word'
[root@localhost shell]# echo $b
hello word
提升局部变量为全局变量export,子bash更改全局变量只在子bash里有效
[root@localhost shell]# export b
[root@localhost shell]# ps -f
UID PID PPID C STIME TTY TIME CMD
root 2097 2088 0 07:35 pts/0 00:00:00 -bash
root 2648 2097 0 08:08 pts/0 00:00:00 ps -f
[root@localhost shell]# bash
[root@localhost shell]# echo $b
hello word
[root@localhost shell]# ps -f
UID PID PPID C STIME TTY TIME CMD
root 2097 2088 0 07:35 pts/0 00:00:00 -bash
root 2649 2097 0 08:08 pts/0 00:00:00 bash
root 2682 2649 0 08:09 pts/0 00:00:00 ps -f
只读变量:readonly
[root@localhost shell]# readonly b=2
[root@localhost shell]# b=q0
-bash: b: 只读变量
撤销变量:unset
[root@localhost shell]# unset a
[root@localhost shell]# echo a
a
特殊变量
$n
[root@localhost shell]# vim hello.sh
#!/bin/bash
echo "hello world"
echo "hello $1"
[root@localhost shell]# . hello.sh xiaoming
hello world
hello xiaoming
[root@localhost shell]# vim hello.sh
#!/bin/bash
echo '========$n========'
echo script name: $0
echo 1st: $1
echo 2nd: $2
[root@localhost shell]# ./hello.sh abc def
========$n========
script name: ./hello.sh
1st: abc
2nd: def
$# 统计参数个数
[root@localhost shell]# vim hello.sh
#!/bin/bash
echo '========$n========'
echo script name: $0
echo 1st: $1
echo 2nd: $2
echo 2th: $3
echo '========$n========'
echo numbers: $#
[root@localhost shell]# ./hello.sh abc def g
========$n========
script name: ./hello.sh
1st: abc
2nd: def
2th: g
========$n========
numbers: 3
$* 此变量代表命令行中所有参数,把所有参数看成一个整体
$@ 此变量代表命令行中所有参数,把所有参数区别对待
[root@localhost shell]# vim hello.sh
#!/bin/bash
echo '========$n========'
echo script name: $0
echo 1st: $1
echo 2nd: $2
echo 2th: $3
echo '========$#========'
echo numbers: $#
echo '========$*========'
echo $*
echo '========$@========'
echo $@
[root@localhost shell]# ./hello.sh abc def g
========$n========
script name: ./hello.sh
1st: abc
2nd: def
2th: g
========$n========
numbers: 3
========$n========
abc def g
========$n========
abc def g
$? 最后一次执行命令的返回状态
[root@localhost shell]# echo $?
0
[root@localhost shell]# 123.sh
bash: 123.sh: 未找到命令...
[root@localhost shell]# echo $?
127
运算符
基本语法
( ( 运算式 ) ) 或者 ((运算式)) 或者 ((运算式))或者[运算式]
[root@localhost shell]# expr 1 + 2
3
[root@localhost shell]# expr 2 * 3
expr: 语法错误
[root@localhost shell]# expr 2 \* 3
6
[root@localhost shell]# echo $[2+3]
5
[root@localhost shell]# a=$(expr 2 \* 3)
[root@localhost shell]# echo $a
6
[root@localhost shell]# vim add.sh
#!/bin/bash
sum=$[$1+$2]
echo sum=$sum
[root@localhost shell]# ./add.sh 23 22
sum=45
条件判断
基本语法
- test 条件表达式
- [条件表达式]
[root@localhost shell]# echo $a
1
[root@localhost shell]# test $a = 3
[root@localhost shell]# echo $?
1 #表示前一个命令错误
[root@localhost shell]# test $a = 1
[root@localhost shell]# echo $?
0 #语法正确
[root@localhost shell]# [ $a = 1 ] #括号中间需要空格
[root@localhost shell]# echo $?
0
[root@localhost shell]# [ $a = 2 ]
[root@localhost shell]# echo $?
1
[root@localhost shell]# [ ]
[root@localhost shell]# echo $?
1
[root@localhost shell]# [ $a != 2 ]
[root@localhost shell]# echo $?
0
常用判断条件
俩个整数比较
- -eq 等于equal
- -ne 不等于not equal
- -lt 小于 less than
- -gt 大于greater than
- -le 小于等于 less equal
- -ge 大于等于 greater equal
字符串比较使用=或者!=
按照文件权限进行判断
- -r 有读的权限read
- -w 有写的权限write
- -x有执行的权限execute
[root@localhost shell]# touch test
[root@localhost shell]# ls
add.sh hello.sh test
[root@localhost shell]# [ -r hello.sh ]
[root@localhost shell]# echo $?
0
[root@localhost shell]# [ -x hello.sh ]
[root@localhost shell]# echo $?
0
[root@localhost shell]# [ -x test ]
[root@localhost shell]# echo $?
1
按照文件类型进行判断
- -e 文件存在
- -f 文件存在是个常规文件
- -d 文件存在且是个目录
[root@localhost shell]# [ -e test ]
[root@localhost shell]# echo $?
0
[root@localhost shell]# [ -f test ]
[root@localhost shell]# echo $?
0
[root@localhost shell]# [ -d test ]
[root@localhost shell]# echo $?
1
多条件判断(&&前一条命令执行成功后执行后一条命令,|| 前一条命令执行失败后执行后一条命令)
[root@localhost shell]# [ -d test ] && echo ok || echo notok
notok
[root@localhost shell]# [ $a -lt 20 ] && echo "$a<20" || echo "$a>=20"
15<20
[root@localhost shell]# [ $a -lt 20 ] && echo "$a<20" || echo "$a>=20"
21>=20
流程控制
if 判断
流程:顺序,分支,循环
单分支
if [条件判断]
then
程序
fi
[root@localhost a]# a=22
[root@localhost a]# if [ $a -gt 18 ]; then echo shuai; fi
shuai
[root@localhost shell]# ./hello.sh zhangheng
welcome,zhangheng
[root@localhost shell]# cat hello.sh
#!/bin/bash
if [ $1 = zhangheng ]
then
echo "welcome,zhangheng"
fi
多分支
if [条件判断]
then
程序
elif [条件判断]
then
程序
else
程序
fi
[root@localhost shell]# if [ $a -gt 18 ] && [ $a -lt 35 ]; then echo OK; fi
OK
[root@localhost shell]# if [ $a -gt 18 -a $a -lt 35 ]; then echo OK; fi
OK #-a为and -o为or
[root@localhost shell]# ./hello.sh zhangheng 22
welcome,zhangheng
成年人
[root@localhost shell]# cat hello.sh
#!/bin/bash
if [ $1 = zhangheng ]
then
echo "welcome,zhangheng"
fi
# 输入年龄,判断有没有成年
if [ $2 -lt 18 ]
then
echo "未成年人"
else
echo "成年人"
fi
case语句
[root@zhangheng shell]# vim case.sh
[root@zhangheng shell]# chmod +x case.sh
[root@zhangheng shell]# ./case.sh 1
one
[root@zhangheng shell]# ./case.sh 6
other number
[root@zhangheng shell]# cat case.sh
#!/bin/bash
case $1 in
1)
echo "one"
;;
2)
echo "two"
;;
3)
echo "three"
;;
*)
echo "other number"
;;
esac
for循环
[root@zhangheng shell]# vim for.sh
[root@zhangheng shell]# ./for.sh 4
10
[root@zhangheng shell]# cat for.sh
#!/bin/bash
for (( i=1; i <= $1; i++ ))
do
sum=$[ $sum + $i ]
done
echo $sum
双小括号内可以使用数学运算符
[root@zhangheng shell]# for i in {1..100}; do sum=$[$sum+$i]; done; echo $sum
5050
while循环
[root@zhangheng shell]# ./while.sh 4
10
[root@zhangheng shell]# cat while.sh
#!/bin/bash
a=1
while [ $a -le $1 ]
do
sum=$[ $sum + $a ]
a=$[ $a + 1 ]
done
echo $sum
read读取控制台输入
[root@zhangheng shell]# ./read.sh
请输入您的芳名:zhangheng
welcome, zhangheng
[root@zhangheng shell]# cat read.sh
#!/bin/bash
read -t 10 -p "请输入您的芳名:" name
echo "welcome, $name"
[root@zhangheng shell]# ./高级智能脱单时间预测系统
请输入您的芳名:hanxu
请输入您的年龄:22
hanxu ,您将在一个月内脱单
您的脱单年龄为:22
您的对象为: 古力娜扎,迪丽热巴,耶斯莫拉
[root@zhangheng shell]# cat 高级智能脱单时间预测系统
#!/bin/bash
read -t 20 -p "请输入您的芳名:" name
read -t 20 -p "请输入您的年龄:" age
sleep 3
echo "$name ,您将在一个月内脱单"
sleep 2
echo "您的脱单年龄为:$age"
sleep 2
echo "您的对象为: 古力娜扎,迪丽热巴,耶斯莫拉"
函数
轻量级脚本,实现特定功能代码的集合
系统函数
可分为内部函数和外部函数
$( ) 功能为命令替换,可以调用系统函数
[root@zhangheng shell]# date
2022年 09月 05日 星期一 08:58:51 CST
[root@zhangheng shell]# date +0%s
01662339565 #当前的时间戳
[root@zhangheng shell]# vim sys.sh
[root@zhangheng shell]# chmod +x sys.sh
[root@zhangheng shell]# ./sys.sh zhangheng
zhangheng_log_1662339884
[root@zhangheng shell]# cat sys.sh
#!/bin/bash
filename="$1"_log_$(date +%s)
echo $filename
basename:会删掉所有前缀包括最后一个/字符,用于取路径里的文件名称
[root@zhangheng shell]# basename /root/shell/sys.sh
sys.sh
[root@zhangheng shell]# basename /root/shell/sys.sh .sh
sys
dirname:返回文件的路径
[root@zhangheng shell]# dirname /root/shell/sys.sh
/root/shell
[root@zhangheng shell]# vim route.sh
[root@zhangheng shell]# chmod +x route.sh
[root@zhangheng shell]# ./route.sh
script name: route
script path: /root/shell
[root@zhangheng shell]# cat route.sh
#!/bin/bash
echo script name: $(basename $0 .sh)
echo script path: $(cd $(dirname $0); pwd)
这俩个命令只是剪切路径这个字符串,并不判断路径的正确性
自定义函数
直接打印结果:
[root@zhangheng shell]# vim fun.sh
[root@zhangheng shell]# ./fun.sh
请输入第一个整数:34
请输入第二个整数:44
俩数字之和:78
[root@zhangheng shell]# cat fun.sh
#!/bin/bash
function add()
{
s=$[$1 + $2]
echo "俩数字之和:$s"
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
add $a $b
返回结果
[root@zhangheng shell]# ./fun.sh
请输入第一个整数:3
请输入第二个整数:12
和为:15
和的平方为:225
[root@zhangheng shell]# cat fun.sh
#!/bin/bash
function add()
{
s=$[$1 + $2]
echo $s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
sum=$(add $a $b)
echo "和为:"$sum
echo "和的平方为:"$[$sum * $sum]
文本归档实践
tar:归档命令 加上-c表示归档,-z表示归档的时候压缩
每日凌晨俩点自动归档/root/shell文件:
[root@zhangheng shell]# mkdir /root/archive
[root@zhangheng shell]# vim daily_archive.sh
#!/bin/bash
# 首先判断输入参数是否唯一
if [ $# -ne 1 ]
then
echo "参数个数错误!应输入一个参数,作为归档目录名"
exit
fi
# 先判断参数是否为目录名,从参数中获取目录名称
if [ -d $1 ]
then
echo
else
echo
echo "目录不存在"
echo
exit
fi
DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)
#获取当前日期
DATE=$(date +%y%m%d)
#定义生成的归档文件名称
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DEST=/root/archive/$FILE
#开始归档目录文件
echo "开始归档..."
echo
tar -czf $DEST $DIR_PATH/$DIR_NAME
if [ $? -eq 0 ]
then
echo
echo "归档成功"
echo "归档文件为:$DEST"
else
echo "归档出现问题"
echo
fi
exit
[root@zhangheng shell]# chmod u+x daily_archive.sh
[root@zhangheng shell]# ./daily_archive.sh ../shell
开始归档...
tar: 从成员名中删除开头的“/”
归档成功
归档文件为:/root/archive/archive_shell_220905.tar.gz
[root@zhangheng shell]# crontab -l
no crontab for root
[root@zhangheng shell]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@zhangheng shell]# crontab -l
0 2 * * * /root/shell/daily_archive.sh /root/shell
正则表达式
^匹配以该字符串开头的行
$匹配以该字符串结尾的行
^$匹配空行
[root@zhangheng shell]# cat daily_archive.sh | grep ^$
[root@zhangheng shell]# cat daily_archive.sh | grep -n ^$
2:
9:
20:
23:
26:
30:
32:
35:
37:
47:
一个点匹配任意一个字符
*指前面一个字符出现任意次
.*指任意字符出现任意次
[root@zhangheng shell]# ls | grep f...sh
for.sh
fun.sh
[root@zhangheng shell]# ls | grep *
[root@zhangheng shell]# ls | grep ^f.*
for.sh
fun.sh
匹配字符区间(中括号)[ ]
- [1,2]匹配1或者2
- [0-9]匹配任何一个数字
- [0-9]*匹配任意多个数字
\转义字符:例如匹配$这种特殊字符时,无法直接匹配,此时使用转义字符,使用时必须使用单引号括起来
[root@zhangheng shell]# cat daily_archive.sh | grep '\$'
if [ $# -ne 1 ]
if [ -d $1 ]
DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)
DATE=$(date +%y%m%d)
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DEST=/root/archive/$FILE
tar -czf $DEST $DIR_PATH/$DIR_NAME
if [ $? -eq 0 ]
echo "归档文件为:$DEST"
有些地方{n}表示前一个字符重复出现n次,此时需要加-E使用
文本处理工具
cut
cut [选项参数] filename
参数说明:
-f 列号,提取第几列
-d 分割符,按照指定分隔符分割列,默认是制表符“\t”
-c 按照字符进行切割,后面加n表示取第几列
[root@zhangheng shell]# cat cut.txt
zhang hen
guan zhen
wo wo
lai lai
le le
[root@zhangheng shell]# cut -d " " -f 1 cut.txt #以空格作为分割符
zhang
guan
wo
lai
le
#截取第1和2列
[root@zhangheng shell]# cut -d " " -f 1,2 cut.txt
zhang hen
guan zhen
wo wo
lai lai
le le
#截取1到2列
[root@zhangheng shell]# cut -d " " -f 1-2 cut.txt
#截取第二个冒号之后的
[root@zhangheng shell]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@zhangheng shell]# echo $PATH | cut -d ":" -f 2-
/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#截取当前IP地址
[root@zhangheng shell]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.2.101 netmask 255.255.255.0 broadcast 192.168.2.255
inet6 fe80::16e7:3caf:8754:bd97 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c5:57:a5 txqueuelen 1000 (Ethernet)
RX packets 839 bytes 71042 (69.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 637 bytes 72043 (70.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@zhangheng shell]# ifconfig ens33 | grep netmask
inet 192.168.2.101 netmask 255.255.255.0 broadcast 192.168.2.255
[root@zhangheng shell]# ifconfig ens33 | grep netmask | cut -d " " -f 10
192.168.2.101
[root@zhangheng shell]# ifconfig | grep netmask | cut -d " " -f 10
192.168.2.101
127.0.0.1
192.168.122.1
awk文本分析工具
[root@zhangheng shell]# which awk
/usr/bin/awk
[root@zhangheng shell]# ll /usr/bin | grep awk
lrwxrwxrwx. 1 root root 4 8月 26 11:31 awk -> gawk
-rwxr-xr-x. 1 root root 514168 6月 29 2017 dgawk
-rwxr-xr-x. 1 root root 428584 6月 29 2017 gawk
-rwxr-xr-x. 1 root root 3188 6月 29 2017 igawk
-rwxr-xr-x. 1 root root 428672 6月 29 2017 pgawk
awk使用方法
grep针对行,cut针对列,awk把文件逐行读入,以空格为默认分隔符将每行切片
awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}’ filename
pattern:正则匹配
action:找到匹配内容时所执行的一系列命令
选项参数
-F 指定输入文件分割符
-v 赋值一个用户的定义变量
#查找root登录时使用的解析器
[root@zhangheng shell]# cat /etc/passwd | grep ^root | cut -d ":" -f 7
/bin/bash
[root@zhangheng shell]# cat /etc/passwd | awk -F ":" '/^root/ {print $7}'
/bin/bash
#提取第一列第七列,输出时以逗号分割
[root@zhangheng shell]# cat /etc/passwd | awk -F ":" '/^root/ {print $1","$7}'
root,/bin/bash
#提取后再第一行和最后一行加上任意内容
[root@zhangheng shell]# cat /etc/passwd | awk -F ":" 'BEGIN{print "user,shell"} /^root/ {print $1","$7} END{print "end of file"}'
user,shell
root,/bin/bash
end of file
将用户uid加一
[root@zhangheng shell]# cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}'
1
2
3
4
5
6
7
8
9
12
13
15
100
193
...
awk内置变量
filename:文件名
nr:已读的记录行(行号)
nf:浏览记录的域的个数
统计文件的文件名,每列的行号,每行的列数:
[root@zhangheng shell]# awk -F ":" '{print "文件名:"FILENAME "行号:"NR "列数:"NF}' /etc/passwd
文件名:/etc/passwd行号:1列数:7
文件名:/etc/passwd行号:2列数:7
文件名:/etc/passwd行号:3列数:7
文件名:/etc/passwd行号:4列数:7
文件名:/etc/passwd行号:5列数:7
文件名:/etc/passwd行号:6列数:7
文件名:/etc/passwd行号:7列数:7
文件名:/etc/passwd行号:8列数:7
文件名:/etc/passwd行号:9列数:7
文件名:/etc/passwd行号:10列数:7
文件名:/etc/passwd行号:11列数:7
输出文本中空行行号:
[root@zhangheng shell]# ifconfig | grep -n ^$
9:
18:
26:
[root@zhangheng shell]# ifconfig | awk '/^$/ {print NR}'
9
18
26
筛选出IP地址
awk默认空格为分割符,默认一行开头所有空格不算
[root@zhangheng shell]# ifconfig | awk '/netmask/ {print $2}'
192.168.2.101
127.0.0.1
192.168.122.1
[root@zhangheng shell]# ifconfig | grep netmask | cut -d " " -f 10
192.168.2.101
127.0.0.1
192.168.122.1
发送消息
使用mesg和write工具
[root@zhangheng shell]# who am i
root pts/0 2022-09-06 17:32 (192.168.2.1)
[root@zhangheng shell]# who
root pts/0 2022-09-06 17:32 (192.168.2.1)
centos :0 2022-09-06 18:00 (:0)
centos pts/1 2022-09-06 18:00 (:0)
centos pts/2 2022-09-06 18:02 (192.168.2.1)
[root@zhangheng shell]# who -T
root + pts/0 2022-09-06 17:32 (192.168.2.1)
centos ? :0 2022-09-06 18:00 (:0)
centos + pts/1 2022-09-06 18:00 (:0)
centos + pts/2 2022-09-06 18:02 (192.168.2.1)
[root@zhangheng shell]# mesg
is y
[root@zhangheng shell]# mesg n
[root@zhangheng shell]# mesg
is n
[root@zhangheng shell]# mesg y
[root@zhangheng shell]# mesg
is y
[root@zhangheng shell]# write centos pts/2
hai,zhangheng
[centos@zhangheng ~]$ hai,zhangheng
编辑脚本
[root@zhangheng shell]# vim xiaoxi.sh
#!/bin/bash
#查看用户是否登录 -i指不区分大小写 -m指不针对第一行 -z判断后面的是否为空
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
if [ -z $login_user ]
then
echo "$1 不在线!"
echo "脚本退出.."
exit
fi
#查看用户是否开启消息功能
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $is_allowed != "+" ]
then
echo "$1 没有开启消息功能"
echo "脚本退出.."
exit
fi
#判断是否有消息发送
if [ -z $2 ]
then
echo "没有消息发出"
echo "脚本退出.."
exit
fi
#获取要发送的消息,先要排除第一个参数,截取第二个及其之后的参数
whole_msg=$(echo $* | cut -d " " -f 2- )
#获取用户登录的终端,who命令执行后的第二列为终端
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
#写入要发送的消息
echo $whole_msg | write $login_user $user_terminal
if [ $? != 0 ]
then
echo "发送失败!"
else
echo "发送成功!"
fi
exit
[root@zhangheng shell]# chmod +x xiaoxi.sh
发送消息
[root@zhangheng shell]# who -T
root + pts/0 2022-09-06 18:37 (192.168.2.1)
centos + pts/1 2022-09-06 18:37 (192.168.2.1)
[root@zhangheng shell]# ./xiaoxi.sh xiaoming
xiaoming 不在线!
脚本退出..
[root@zhangheng shell]# ./xiaoxi.sh centos
没有消息发出
脚本退出..
[root@zhangheng shell]# ./xiaoxi.sh centos hello,zhangheng
发送成功!
[centos@zhangheng ~]$
Message from root@zhangheng on pts/0 at 18:39 ...
hello,zhangheng
EOF
then
echo “$1 不在线!”
echo “脚本退出…”
exit
fi
#查看用户是否开启消息功能
is_allowed=$(who -T | grep -i -m 1 $1 | awk ‘{print $2}’)
if [ $is_allowed != “+” ]
then
echo “$1 没有开启消息功能”
echo “脚本退出…”
exit
fi
#判断是否有消息发送
if [ -z $2 ]
then
echo “没有消息发出”
echo “脚本退出…”
exit
fi
#获取要发送的消息,先要排除第一个参数,截取第二个及其之后的参数
whole_msg=$(echo $* | cut -d " " -f 2- )
#获取用户登录的终端,who命令执行后的第二列为终端
user_terminal=$(who | grep -i -m 1 $1 | awk ‘{print $2}’)
#写入要发送的消息
echo $whole_msg | write $login_user $user_terminal
if [ $? != 0 ]
then
echo “发送失败!”
else
echo “发送成功!”
fi
exit
[root@zhangheng shell]# chmod +x xiaoxi.sh
发送消息
[root@zhangheng shell]# who -T
root + pts/0 2022-09-06 18:37 (192.168.2.1)
centos + pts/1 2022-09-06 18:37 (192.168.2.1)
[root@zhangheng shell]# ./xiaoxi.sh xiaoming
xiaoming 不在线!
脚本退出…
[root@zhangheng shell]# ./xiaoxi.sh centos
没有消息发出
脚本退出…
[root@zhangheng shell]# ./xiaoxi.sh centos hello,zhangheng
发送成功!
[centos@zhangheng ~]$
Message from root@zhangheng on pts/0 at 18:39 …
hello,zhangheng
EOF