Shell
linux内核(kernel),操作计算机硬件资源,告诉CPU干什么、需要多少内存...
linux用户操作作用在外层应用程序,内核不能直接识别用户的操作指令,需要借助Shell命令行解释器(解释、调用程序,向内核发起申请),才能让内核完成命令操作
查看Linux下的shell的解释器
默认bash shell
Hello Word案例
shell脚本一般一.sh为后缀,且第一行必须是 #!/bin/bash 或者 #!/bin/sh
执行脚本
1.sh、bash + 脚本相对或绝对路径
2.对文件添加可执行权限X,./脚本文件执行
3.对文件添加可执行权限X,用 “.” 或者“source” + 文件相对路径或绝对路径==不会启动子shell==
==.和./执行的逻辑不一样,.是命令,./是当前目录下执行某文件==
变量
全局变量:当前的shell和子shell都可以访问
局部变量:只对当前shell有作用,其余子shell和父shell都不管用
1.常用系统变量
$HOME 家目录
$PWD 当前目录
查看全部全局变量:env 或者printenv==(只是系统的全局变量)==
查看具体某一个环境变量:printenv + 变量名
set查看系统的全局变量和局部变量,==包括自己定义的==
自定义变量(默认定义为字符串)
局部变量
变量名=变量值,===前后不能有空格==
变量值如果有空格,使用双引号
myname=“wang tao”
全局变量
export myname,寓意为导出,子shell即可生效
如果在子shell更改,退出子shell后不生效,只在子shell或者子shell的子shell生效
查看子shell进程 ps -f,bash启动新子shell
==局部变量输出==
1.使用“.”或者“source”,在当前shell执行,不启动子shell即可生效
2.使用export将局部变量变为全局变量
只读变量(不能更改的常量)
readonly a=wang
变量常量的撤销
unset + 变量名,==常量不可uset==
变量名规则
1.不能以数字开头,==环境变量名建议大写==
2.bash中默认变量类型为字符串类型,无法直接数值运算
3.变量值有空格,需要用单/双引号
创建脚本命令
将脚本文件放在/bin/下,输入脚本文件名即可执行(带后缀)
特殊变量
1.$n
$n(n为数字,0表示脚本名称,(1-9)表示第一到第九个参数),十以上的参数需要用{},{10}
示例
#!/bin/sh
echo "Hello Word! SH "
echo "Hello,$1"
echo "Hello $0"
执行
# ./hello.sh wangtao
Hello Word! SH
Hello,wangtao
Hello ./hello.sh
单引号中不会编译特殊符号,会按照源字符输出
#!/bin/bash
echo '========$0========='
echo script name: $0
echo 1st paramater: $1
echo 2nd parameter: $2
# ./part wang liu
========$0=========
script name: ./part
1st paramater: wang
2nd parameter: liu
2.$
获取当前输入参数的个数,常用于循环(参数个数失败会报错)
#!/bin/bash
echo '========$0========='
echo script name: $0
echo 1st paramater: $1
echo 2nd parameter: $2
echo parameter number: $#
[root@sre_shell ~]# ./part wang liu
========$0=========
script name: ./part
1st paramater: wang
2nd parameter: liu
parameter number: 2
3.$*
$* :代表命令行中所有的参数,会把所有参数看成一个整体
$@:代表命令行所有参数,把每个参数区分对待(数组)
echo $*
echo $@
# ./part wang liu
wang liu
wang liu
不加"" 两者没有区别
[root@sre_shell ~]# cat parameter_for.sh
#!/bin/bash
echo '$*'
for para in "$*"
do
echo $para
done
echo '$@'
for para in "$@"
do
echo $para
done
[root@sre_shell ~]# ./parameter_for.sh a b c e
$*
a b c e
$@
a
b
c
e
4.$?
返回最后一次执行命令返回状态,如果为0,表示成功执行,如果非0(不同数值表示不同错误),表示不正确
运算符
赋值默认为字符串,不可直接做运算
expr 1 + 1,expr 3 * 9 注意有空格
赋值格式
[root@sre_shell ~]# a=$((1+9))
[root@sre_shell ~]# echo $a
10
[root@sre_shell ~]# a=$[9*3]
[root@sre_shell ~]# echo $a
27
[root@sre_shell ~]# a=$[(2+3)*4] && echo $a
20
expr赋值格式
[root@sre_shell ~]# a=$(expr 9 \* 2)
[root@sre_shell ~]# echo $a
18
[root@sre_shell ~]# a=`expr 9 / 3`
[root@sre_shell ~]# echo $a
3
加法脚本
[root@sre_shell ~]# cat add.sh
echo $[$1+$2]
[root@sre_shell ~]# ./add.sh 2 3
5
条件判断
基本语法 test + 条件表达式(==前后面有空格,否则都为0==)
[root@sre_shell ~]# test $a = hello
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# test $a = hell
[root@sre_shell ~]# echo $?
1
等价于==[ ]也有空格==
[root@sre_shell ~]# [ $a = hello ]
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ $a = hell ]
[root@sre_shell ~]# echo $?
1
= ,!=是判断字符串是否相等
[ 2 != 2 ] 1 这里比较的是字符串比较
-a -o
在同一个[ ]中可以用-a参数表示&&,-o表示||
[root@sre_shell ~]# echo $a
20
[root@sre_shell ~]# if [ $a -gt 18 ] && [ $a -lt 30 ]; then echo OK; fi
OK
[root@sre_shell ~]# if [ $a -gt 18 -a $a -lt 30 ]; then echo OK; fi
OK
[root@sre_shell ~]# if [ $a -gt 30 -o $a -lt 18 ]; then echo OK; fi
[root@sre_shell ~]#
[] 空值为 1 (假)
数值之间的比较参数
-eq 等于 -ne 不等于 -lt 小于
-le小于等于 -gt大于 -ge大于等于
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ 8 -eq 8 ]
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ 8 -ne 8 ]
[root@sre_shell ~]# echo $?
1
[root@sre_shell ~]# [ 8 -lt 8 ]
[root@sre_shell ~]# echo $?
1
[root@sre_shell ~]# [ 8 -le 8 ]
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ 8 -gt 8 ]
[root@sre_shell ~]# echo $?
1
[root@sre_shell ~]# [ 8 -ge 8 ]
[root@sre_shell ~]# echo $?
0
判断文件权限
-r 有读的权限 -w 有写的权限 -x有执行的权限
[root@sre_shell ~]# ls -l part
-rwxr-xr-x. 1 root root 148 Mar 4 08:01 part
[root@sre_shell ~]# [ -r part ] && [ -w part ]
[root@sre_shell ~]# echo $?
0
判断文件类型
-e 表示文件存在 -f 表示存在且是一个常规文件 -d存在且是目录
[root@sre_shell ~]# ls
add.sh anaconda-ks.cfg hello.sh part test
[root@sre_shell ~]# [ -e part ]
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ -f part ]
[root@sre_shell ~]# echo $?
0
[root@sre_shell ~]# [ -d part ]
[root@sre_shell ~]# echo $?
1
[root@sre_shell ~]# [ -d test ]
[root@sre_shell ~]# echo $?
0
==案例(三元)==
A&&B||C:A真执行B,否则执行C
[root@sre_shell ~]# [ $a -lt 300 ] && echo "$a<300" || echo "$a>300"
200<300
[]有字符串为真,空为假
[root@sre_shell ~]# [ ] && echo "ok" || echo "nook"
nook
流程控制
1.if
单分支
if [ 条件判断 ];then #常用于命令行
程序
fi
或者
if [ 条件判断 ] #常用于文本脚本
then
程序
fi
例
[root@sre_shell ~]# if [ $a -gt 18 ]; then echo OK; fi
OK
==传参防空==
[root@sre_shell ~]# cat iftest
#!/bin/bash
if [ "$1"x = "wang"x ] #字符串拼接原理,保证有一个字母
then
echo "hello,$1"
fi
多分支
if [ 条件判断 ]
then
程序
elif [ 条件判断 ]
then
程序
else
程序
fi
if [ $2 -lt 22 ]
then
echo "<22"
elif [ $2 -lt 25 ]
then
echo "<25"
else
echo ">25"
fi
[ ]中的条件判断两边必须要有空格 ,if elif 后面有空格
2.case
case $变量名 in
"值1")
如果变量=值1,执行程序1
;;
"值2")
如果变量=值2,执行程序2
;;
*)
都不满足就执行此程序
;;
esac
[root@sre_shell ~]# ./case.sh 40
年轻
[root@sre_shell ~]# ./case.sh 60
老了
[root@sre_shell ~]# ./case.sh 30
加油
[root@sre_shell ~]# cat case.sh
#!/bin/bash
case $1 in
"60") # 60)可以不用""
echo "老了"
;;
"40")
echo "年轻"
;;
*)
echo "加油"
;;
esac
循环
1.for
for ((初始值;循环控制条件;变量变化))
do
程序
done
[root@sre_shell ~]# chmod +x for.sh
[root@sre_shell ~]# ./for.sh
5050
[root@sre_shell ~]# cat for.sh
#!/bin/bash
sum=0
for((i=0;i<=100;i++))
do
sum=$[$sum+$i] #内层$只是字符串拼接,外层$[]是按数值运算
done
echo $sum
传参式
[root@sre_shell ~]# cat sum1.sh
#!/bin/bash
sum=0
for (( i=1;i<=$1;i++))
do
sum=$[ $sum + $i ]
done
echo $sum
[root@sre_shell ~]# ./sum1.sh 100
5050
2.定值for
#!/bin/bash
for os in linux windows macos
do
echo $os
down
[root@sre_shell ~]# ./dfor
linux
windows
macos
[root@sre_shell ~]# for os in window linux macos; do echo $os;done
window
linux
macos
3.增强型{1..100}
[root@sre_shell ~]# for i in {1..100}; do sum=$[$sum+$i]; done; echo $sum
5050
[root@sre_shell ~]# ./for.sh
5050
[root@sre_shell ~]# cat for.sh
#!/bin/bash
sum=0
for i in {1..100}
do
sum=$[$sum+$i] #内层$只是字符串拼接,外层$[]是按数值运算
done
echo $sum
4.while循环
while [ 条件判断 ]#循环外的初始值
do
程序 #包含程序结束条件
done
[root@sre_shell ~]# cat while.sh
#!/bin/bash
a=1
while [ $a -le $1 ]
do
sum2=$[$sum2+$a]
a=$[$a+1]
done
echo $sum2
[root@sre_shell ~]# ./while.sh 100
5050
5.let(转义别的语法==C==)
let+C语言语法
#!/bin/bash
a=1
while [ $a -le $1 ]
do
let sum2+=a
let a++
done
echo $sum2
读取控制台
read读取控制台
从控制台读取用户的输入
read (选项) (参数) #有空格
-p 输入前的提示符
-t 指定等待时间(不加表示一直等待)
参数 指定读取值的变量名
[root@sre_shell ~]# cat read.sh
#!/bin/bash
read -t 10 -p "请输入:" name #注意空格
echo "Hello $name"
[root@sre_shell ~]# ./read.sh
请输入:wang
Hello wang
read+条件判断
[root@sre_shell ~]# cat read.sh
#!/bin/bash
read -t 3 -p "请输入:" name
if [ $name ]
then
echo "Hello $name"
else
echo "no name"
fi
[root@sre_shell ~]# ./read.sh
请输入:wang
Hello wang
[root@sre_shell ~]# ./read.sh
请输入:no name
函数
系统函数
轻量化脚本
==变量+系统时间戳==
[root@sre_shell ~]# cat namedate.sh
#!/bin/bash
filename="$1"_logtime_$(date +%s)
echo $filename
[root@sre_shell ~]# ./namedate.sh testname
testname_logtime_1709686703
[root@sre_shell ~]# date +%s
1709686712
==basename==
截取文件路径的文件名称(去掉路径也可去掉后缀)
basename /home/test/wang.test
wang.test
basename /home/test/wang.text .text
wang
==实际用法:生产带时间戳、拼接等字符串时 不能带上文件路径和后缀==
[root@sre_shell ~]# cat srcipt.sh
#!/bin/bash
echo script_name: $0
[root@sre_shell ~]# ./srcipt.sh
script_name: ./srcipt.sh
[root@sre_shell ~]# /root/srcipt.sh
script_name: /root/srcipt.sh #$0会取到文件路径和后缀
改进
#!/bin/bash
echo script_name: $(basename $0 .sh) #用()添加系统命令
[root@sre_shell ~]# ./srcipt.sh
script_name: srcipt
dirname
和basename相反,==截取最后一个/之前的路径==
不管相对还是绝对路径,当做字符串处理,截取最后/前字符
[root@sre_shell ~]# dirname /root/while.sh
/root
[root@sre_shell ~]# dirname /root/wang/test
/root/wang #不管路径或者文件存不存在
脚本输出文件绝对路径
即使使用相对路径调用脚本也会获取绝对路径
[root@sre_shell ~]# cat dirname.sh
#!/bin/bash
cd $(dirname $0)
echo script path: $(pwd)
简化
[root@sre_shell ~]# cat dirname.sh
#!/bin/bash
echo script path: $(cd $(dirname $0); pwd) #dirname有可能读取是相对路径,使用pwd获取绝对路径
[root@sre_shell ~]# ./dirname.sh
script path: /root
自定义函数
function functionname()
{
Action;
[return int;]
}
必须在调用函数前声明函数,shell是逐行运行
函数返回值只能通过$?获取,return返回 如果不加就以最后一条命令运行结果作为返回值,return后跟数值n(0-255)
函数定义和调用
[root@sre_shell ~]# cat funtionname.sh
#!/bin/bash
function sum()
{
s=$[$1+$2]
echo "sum="$s
}
read -p "number1: " a
read -p "number2: " b
sum $a $b
[root@sre_shell ~]# ./funtionname.sh
number1: 23
number2: 43
sum=66
有返回值
[root@sre_shell ~]# cat funtionname.sh
#!/bin/bash
function sum()
{
s=$[$1+$2]
return $s
}
read -p "number1: " a
read -p "number2: " b
sum $a $b
echo $? # $?的取值范围是0-255,超出即进入下一次循环
[root@sre_shell ~]# ./funtionname.sh
number1: 255
number2: 5
sum=4
优化
用return后,¥?只能捕获0-255,所以不用$?捕获
#!/bin/bash
function sum()
{
s=$[$1+$2]
echo $s
}
read -p "number1: " a
read -p "number2: " b
sum=$(sum $a $b) #将函数echo的值转换并赋值
echo "sum="$sum
echo "sum^2="$[$sum*$sum] #二次计算
正则
正则表达式使用单个字符申来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来==检索、替换那些符合某个模式的文本==。在Linux中,grep,sed,awk等文本处理工具都支持通过正则表达式进行模式匹配。
用来定义一个模糊检索规则
常用于模糊检索;以什么开头的IP、什么结尾的文件
1.常规匹配
[root@kernel_shell archive]# cat /etc/passwd | grep wang
wang:x:1000:1000::/home/wang:/bin/bash
2.常用特殊字符
^ ;匹配一行的开头
可以接一个字符和一个字符串
[root@kernel_shell archive]# cat /etc/passwd | grep ^w #以w字母开头的
wang:x:1000:1000::/home/wang:/bin/bash
wangtao:x:1001:1001::/home/wangtao:/bin/bash
$ ;匹配一行的结束
h$ 匹配以h结尾的行
[root@kernel_shell archive]# cat /etc/passwd | grep h$
root:x:0:0:root:/root:/bin/bash
wang:x:1000:1000::/home/wang:/bin/bash
wangtao:x:1001:1001::/home/wangtao:/bin/bash
如果同时出现^,$,中间匹配的字符必须是和那一行一模一样才会匹配成功
[root@kernel_shell archive]# cat /etc/passwd | grep ^wang:x:1000:1000::/home/wang:/bin/bash$
wang:x:1000:1000::/home/wang:/bin/bash
[root@kernel_shell archive]#
^,$之间如果没有字符,则是匹配空行
[root@kernel_shell archive]# cat /root/archive/kong.sh | grep -n ^$
1:
2:k
3:
4:
[root@kernel_shell archive]#
-n 显示空行所在的行号
“ . ” 任意一个字符
“ . ”匹配任意==一个==字符
[root@kernel_shell archive]# cat /etc/passwd | grep r..t
#r和t之间只有两个字符的
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
dockerroot:x:997:994:Docker User:/var/lib/docker:/sbin/nologin
“ * ”上个字符0此和多次
匹配*前面字符0此和多次
[root@kernel_shell archive]# cat /etc/passwd | grep ro*t
#匹配到有 rt、rot、root、roooot......等的行
.*可以匹配任何行
==^$,.*联用==
.*可用于限定开头和结尾,不限定中间字符的正则
[root@kernel_shell archive]# cat /etc/passwd | grep ^w.*sh$
wang:x:1000:1000::/home/wang:/bin/bash
wangtao:x:1001:1001::/home/wangtao:/bin/bash
[root@kernel_shell archive]# cat /etc/passwd | grep ^a.*var.*in$
# a任意var任意in的行
adm:x:3:4:adm:/var/adm:/sbin/nologin
字符串区间“[]”
[ ] 表示匹配某个范围的一个字符
[6,8]:匹配6或8
[0-9]:匹配0-9的数字
[0-9]*:匹配任意长度的数字字符串
[a-z]:匹配一个a-z之间的字符
[a-z]*:匹配任意长度的字母字符串
[a-c,e-f]:匹配a-c或者e-f之间的任意字符
[root@kernel_shell ~]# cat /etc/passwd | grep r[a,b]t #可以不加“,”
[root@kernel_shell ~]# echo "raaaabbbbabat" | grep r[ab]*t
raaaabbbbabat
[root@kernel_shell ~]# echo "rabt" | grep r[ab]t
无结果,[ab],[a,b]都只匹配一个字符a,b
[root@kernel_shell ~]# cat /etc/passwd | grep r[a-z]*t
转义
特殊字符无法加入正则,需要借助转义符号 \
[root@kernel_shell ~]# cat read.sh | grep '\$'
if [ $name ]
echo "Hello $name"
匹配的字符串:'/root/\$name'
判断合法手机号码
[root@kernel_shell ~]# echo 17628274871 | grep ^1[3456789][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
17628274871
[root@kernel_shell ~]# echo 12628274871 | grep ^1[3456789][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
[root@kernel_shell ~]#
脚本
[root@kernel_shell ~]# cat phonenumber.sh
#!/bin/bash
read -p "请输入手机号码:" number
number=$[$(echo $number | grep ^1[3456789][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$)]
if [ $number -eq 0 ]
then
echo "手机号格式错误"
else
echo "手机号格式正确"
fi
[root@kernel_shell ~]# ./phonenumber.sh
请输入手机号码:17628274871
手机号格式正确
[root@kernel_shell ~]# ./phonenumber.sh
请输入手机号码:12545698965
手机号格式错误
[root@kernel_shell ~]# ./phonenumber.sh
请输入手机号码:175282448911
手机号格式错误
正则优化
==-E参数==表示支持扩展正则表达:{},?......
grep -E ^1[3456789][0-9]{9}$
#出现9次
文本处理工具
cut
负责剪切数据,cut从文件的每一行剪切字节、字符、字段并将这些字节字符字段输出;
cut [选项参数] filename ls | cut (捕获剪切)
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 按照指定分隔符分割列,默认制表符“t” |
-c | 按字符切割,后加n表示取第几列:-c 1 |
-d从第一行开始,遇到“”中匹配的字符中断,不包含本字符,作为一列,进入下一行
[root@kernel_shell ~]# cat cut.txt
name age address
wang 20 sichuan
liu 24 bazhong
zhang 32 guiyang
[root@kernel_shell ~]# cut -d " " -f 1 cut.txt 以空格为分割
name
wang
liu
zhang
[root@kernel_shell ~]#
[root@kernel_shell ~]# cut -d "a" -f 1 cut.txt
n
w
liu 24 b
zh
[root@kernel_shell ~]#
区间剪切
[root@kernel_shell ~]# cut -d " " -f 2,3 cut.txt
表示将每行以“ ”空格隔开,提取第二列和第三列
age
20
32
[root@kernel_shell ~]# cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,7
root:/root:/bin/bash
wang:/home/wang:/bin/bash
wangtao:/home/wangtao:/bin/bash
-f 7- :7行以后
-f -4 :4行之前
[root@kernel_shell ~]# echo $PATH | cut -d ":" -f 3-
/usr/sbin:/usr/bin:/root/bin
截取IP地址
==有多少空格就算多少列==
[root@kernel_shell ~]# ip a | grep ens33$ | cut -d " " -f 6
192.168.10.144/24
[root@kernel_shell ~]#
awk(gawk)
grep+cut
文本分析工具,把文件逐行读入,以空格为默认分隔符将每行就行切片,切片的部分再进行分析处理;
awk [选项参数] '/pattern/{action} /pattern2/{action}...' filebame
pattern: 表示awk在数据中查找的内容,就是匹配模式
action: 在找到匹配内容时所执行的一系列命令
-F:指定输入文件分隔符
-v:赋值一个用户定义变量
搜索passwd 文件以root关键字开头的所有行,并输出该行的第7列。
[root@kernel_shell ~]# awk -F : '/^root/{print $7}' passwd
/bin/bash
: 表示指定分割字符为 : ,
讲符合正则的代码块切片,每个参数代表列号
等价
[root@kernel_shell ~]# cat passwd | grep ^root | cut -d ":" -f 7
/bin/bash
搜索passwd 文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
[root@kernel_shell ~]# awk -F : '/^root/{print $1","$7}' passwd
root,/bin/bash
grep+cut不好实现
[root@kernel_shell ~]# cat passwd | grep ^root | cut -d ":" -f 1","7
root:/bin/bash
只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell 在最后一行添加"dahaige,/bin/zuishuai"。
[root@kernel_shell ~]# awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/nihao"}' passwd
user, shell
wang,/bin/bash
wangtao,/bin/bash
dahaige,/bin/nihao
==BEGIN在所有数据读取前执行,END在所有数据执行之后执行==
将passwd文件中的用户id增加数值1并输出
[root@kernel_shell ~]# awk -F ":" '{print $3+1}' passwd
用户定义参数优化
[root@kernel_shell ~]# awk -F ":" -v i=1 '{print $3+i}' passwd
awk内置变量
FILENAME:文件名
NR:已读的记录数(行号)
NF:浏览记录的域的个数(切割后,列的个数)
统计passwd文件名,每行的行号,每行的列数
[root@kernel_shell ~]# awk -F ":" '{print "文件名:" FILENAME"行号:"NR "列数:"NF}' passwd
文件名:passwd行号:22列数:7
文件名:passwd行号:23列数:7
awk输出空行行号
[root@kernel_shell ~]# cat awk_kong.txt | awk '/^$/ {print NR}'
2
4
5
如果使用grep,默认格式会带“:”且无法更改
[root@kernel_shell ~]# cat awk_kong.txt | grep -n ^$
2:
4:
5:
优化捕获IP
[root@kernel_shell ~]# ip a | awk -d '/ens3.$/ {print $2}'
192.168.10.144/24
综合案例
归档文件
实际生产中需要对重要数据就行归档备份
需求:实现一个每天对指定目录备份的脚本;输入一个目录名称(末尾不带/),将目录下的所有文件按天归档保存,将日期附加在归档文件名上,放在/root/archive下。
tar -c表示归档、-z表示压缩,后缀为.tar.gz
#!/bin/bash
#判断输入参数是否唯一
if [ $# -ne 1 ]
then
echo "参数个数错误(一个参数作为归档目录名)"
exit
fi
#从参数中获取目录名称
if [ -d $1 ] #判断目录是否存在
then
echo
else
echo "目录不存在"
exit
fi
dirname=$(basename $1)
dirpath=$(cd $(dirname $1); pwd)
#获取当前日期
date=$(date +%y%m%d)
#定义生成的归档文件名称
filename=archive_${dirname}_$date.tar.gz
dest=/root/archive/$filename
#开始归档
echo "开始归档"
tar -czf $dest $dirpath/$dirname
if [ $? -eq 0 ]
then
echo "归档成功!"
echo "归档文件为:$dest"
else
echo "出现错误;"
echo
fi
exit
[root@kernel_shell archive]# ls
archive_archive_240306.tar.gz dayarc.sh
定时任务的设定
crontab -e -u root
* 2 * * * /root/archive/dayarc.sh /root/archive #每天凌晨两点
[root@kernel_shell archive]# crontab -l
* 2 * * * /root/archive/dayarc.sh /root/archive
发送消息
利用linux自带的mesg和write工具,向其他用户发送消息
需求:实现向某个用户快速发送消息的脚本,输入用户作为第一个参数,后面接着需要发送的消息。脚本需要检测用户是否登录在系统中,是否打开消息功能,以及发送内容是否为空...
#!/bin/bash
#检测/passwd/文件是否存在输入的用户
#此模块尚未完善 可去除不影响正常功能
check_user=$(cat/etc/passwd | awk -d ":" -f 1 )
if [ -z check_user ]
then
echo "未检索到用户$check_user!"
echo "脚本退出!"
exit
else
sleep 1
echo "检索到$check_user 用户"
# 1查看用户是否登录
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
# -i表示过滤忽略大小写 -m表示匹配最大值,只取第一个
if [ -z $login_user ] #-z参数查看字符串是否为空
then
echo "$1 不在线!"
echo "脚本退出!"
exit
else
sleep 1
echo "$1 检索在线"
fi
# 2查看用户是否开启mesage
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $is_allowed != "+" ]
then
echo "$1 没有开启mesage功能!"
echo "脚本退出!"
exit
else
sleep 1
echo "$1 mesage状态正常;"
fi
# 3判断消息内容是否为空
if [ -z $2 ]
then
echo "消息为空!"
echo "脚本退出!"
exit
else
sleep 1
echo "开始发送消息"
fi
#从参数中获取要发送的消息
whole_msg=$(echo $* | cut -d " " -f 2-)
#获取用户登录终端
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
sleep 2
echo "脚本执行结束!"
评论