shell

1.入门

[root@localhost /]# mkdir ./scripts/
[root@localhost /]# cd ./scripts/
[root@localhost scripts]# touch hello.sh
[root@localhost scripts]# vim hello.sh

hello.sh

#!/bin/bash/
echo "你好,世界"
[root@localhost scripts]# ls
hello.sh
[root@localhost scripts]# sh ./hello.sh 
你好,世界
[root@localhost scripts]# bash ./hello.sh 
你好,世界

#或者,加可执行权限,再直接./hello.sh 执行
#第一种是在子bash环境下运行,第二种是在当前bash环境下运行
#运行#type source 可以看到source是shell一个内嵌
#子bash中设置变量,父bash不可见

[root@localhost scripts]# chmod +x hello.sh 
[root@localhost scripts]# ./hello.sh 
你好,世界
[root@localhost scripts]# source ./hello.sh 
你好,世界

2.变量

全局变量:嵌套的子bash可以访问

局部变量:只有当前bash能访问,父、子bash均不能访问

常用系统变量

$HOME、$PWD、$SHELL、$USER

查看当前所有系统变量 env

查看当前所有变量 set

3.用户自定义变量

语法,name=value

=左右不能有空格;声明变量无需$,但是使用时需要$;定义字符串需要引号

[root@localhost scripts]# amax=1000
[root@localhost scripts]# bmax="你好 星期三"
[root@localhost scripts]# echo $amax $bmax 
1000 你好 星期三
[root@localhost scripts]# env | grep amax
[root@localhost scripts]# set | grep amax
amax=1000

#set看变量是否为局部变量,env是全局变量
#用法 set | grep 变量名

通过export 变量名声明全局变量

子bash中修改父bash的全局变量,只会在当前环境下生效,父bash中还是原样不会被修改

4.只读变量和撤销变量

弱类型,理解成全都是字符串,要进行数值运算,使用$((a+b))、$[a+b]

[root@localhost scripts]# hello=10+10
[root@localhost scripts]# echo $hello 
10+10
[root@localhost scripts]# hello=$((10+10))
[root@localhost scripts]# echo $hello
20
[root@localhost scripts]# hello=$[10+20]
[root@localhost scripts]# echo $hello
30

只读变量:readonly声明后,不许修改

[root@localhost scripts]# readonly hello=111
[root@localhost scripts]# echo $hello
111
[root@localhost scripts]# hello=1234
-bash: hello: 只读变量

撤销变量:定义后可以unset撤销,只读变量不能撤销

[root@localhost scripts]# age=18
[root@localhost scripts]# echo $age
18
[root@localhost scripts]# unset age
[root@localhost scripts]# echo $age
[root@localhost scripts]# unset hello 
-bash: unset: hello: 无法反设定: 只读 variable


5.特殊变量

$n代表可接受参数,n是数字,$1-9,表示第1-9个参数,10以上用${10},$0表示当前脚本名称

hello.sh


#!/bin/bash
echo "你好,$1"
[root@localhost scripts]# ./hello.sh 小王
你好,小王

hello.sh

$n 用单引号,表示字符串,而不是变量

#!/bin/bash/
echo '$n'
echo 1st:$1
echo 2nd:$2
echo $0
[root@localhost scripts]# ./hello.sh
$n
1st:
2nd:
./hello.sh
[root@localhost scripts]# ./hello.sh 王 李
$n
1st: 王
2nd: 李
./hello.sh

$# 获取输入参数个数

hello.sh

#!/bin/bash/
echo '$n'
echo 1st:$1
echo 2nd:$2
echo $0
echo $#
[root@localhost scripts]# ./hello.sh
$n
1st:
2nd:
./hello.sh
0
[root@localhost scripts]# ./hello.sh 王 李
$n
1st: 王
2nd: 李
./hello.sh
2

$*,$@,代表命令行所有参数,$*把参数1234 456 看作一个整体,$@ 把每个数据分开,换行显示  没有循环遍历时,二者效果一致。

$? 最后一次执行命令的状态

命令正确执行,返回0。非零就是运行错误

[root@localhost scripts]# echo $?
0
[root@localhost scripts]# hello.sh
bash: hello.sh: 未找到命令...
[root@localhost scripts]# echo $?
127

6.运算符

表达式expr,expr 10 + 10,其中10,+,10分别时表达式三个参数。要有空格,不能写成expr 10+10。乘不能直接写*,因为其通常是作为通配符,表示0或多个字符,要转义\*,如expr 10 \* 5。

赋值给变量时用a=$(expr 10 + 5),或者a =`expr 12 + 12`

$((10 + 123))或者$[ 11 * 22 ]也可以实现

()或者[]中不需要转义\*,是因为括号里并没有进行数学运算,在expr表达式里就需要转义,因为它执行了数学运算。

[root@localhost scripts]# expr 10+10
10+10
[root@localhost scripts]# expr 10 + 10
20
[root@localhost scripts]# expr 10 * 3
expr: 语法错误
[root@localhost scripts]# expr 10 \* 3
30
[root@localhost scripts]# c=expr 10 + 15
bash: 10: 未找到命令...
[root@localhost scripts]# c="expr 10 + 15"
[root@localhost scripts]# echo $c
expr 10 + 15
[root@localhost scripts]# c=$(expr 10 + 15)
[root@localhost scripts]# echo $c
25
[root@localhost scripts]# s=$[(5 + 5) * 9]
[root@localhost scripts]# echo $s
90


7.条件判断

等于 =

test $a = 10,=前后加空格,避免被解析成一个整体

[ a = b ],前后必须有空格

不等于 !=

[root@localhost scripts]# a=10
[root@localhost scripts]# test $a = 10
[root@localhost scripts]# echo $?
0
[root@localhost scripts]# test $a = 11
[root@localhost scripts]# echo $?
1
[root@localhost scripts]# test $a=11
[root@localhost scripts]# echo $?
0


[root@localhost scripts]# [ $a = 11 ]
[root@localhost scripts]# echo $?
1
[root@localhost scripts]# [ $a=11 ]
[root@localhost scripts]# echo $?
0

[root@localhost scripts]# [ $a != 11 ]
[root@localhost scripts]# echo $?
0
[root@localhost scripts]# [ $a!=10 ]
[root@localhost scripts]# echo $?
0

两个值比较

-eqequal-nenot equal
-ltless than-leless equal
-gtgreater than-gegreater equal

用法:[ $a -eq $b ]

[root@localhost ~]# a=10
[root@localhost ~]# b=10
[root@localhost ~]# [ $a -eq $b ]
[root@localhost ~]# echo $?
0


[root@localhost ~]# a=20
[root@localhost ~]# [ $a -ne $b ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $a -le $b ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ $a -ge $b ]
[root@localhost ~]# echo $?
0

文件权限判断

-r,-w,-x,读写执行

[root@localhost scripts]# [ -r yunsuan.sh ]
[root@localhost scripts]# echo $?
0

文件类型判断

-e,文件是否存在

-f,存在且是file类型

-d,存在且是directory类型

[root@localhost scripts]# [ -e yunsuan.sh ]
[root@localhost scripts]# echo $?
0
[root@localhost scripts]# [ -f yunsuan.sh ]
[root@localhost scripts]# echo $?
0
[root@localhost scripts]# [ -d yunsuan.sh ]
[root@localhost scripts]# echo $?
1

多条件判断

&&,与,两者都成立

||,或,二者有一成立。第一个条件失败后再执行第二个条件的判断

[root@localhost scripts]# [ -e yunsuan.sh ] && [ 10 -ge 10 ]
[root@localhost scripts]# echo $?
0

衍生:类似三元运算符

&& ||,如:

[root@localhost scripts]# [ $a -eq $b ] && echo "$a=$b" || echo "$a!=$b" 
20!=10

8.流程控制

if条件判断,格式:

if [条件]; then
    语句; 
fi


#或者

if [条件]
then
    语句
fi
[root@localhost scripts]# if [ $a != 10 ]; then echo "ok"; fi 
ok

第二种要以文件方式才可运行

#!/bin/bash
if [ "$1"x != "10"x ]
then
echo "ok"
fi

多条件判断时&&,||不能写在中括号[]里,但是可以用-a,-o连接,and,or

[root@localhost scripts]# if [ $a = 20 -a $b = 10 ]; then echo "ok"; fi
ok
[root@localhost scripts]# if [ $a = 10 -o $b = 10 ]; then echo "ok"; fi
ok

if else,条件分支

#!/bin/bash
if [ "$1" -lt 18 ]
then
echo "未成年"
else
echo "成年人"
fi

if elif else,多分支

#!/bin/bash
if [ "$1" -lt 18 ]
then
        echo "未成年"
elif [ "$1" -lt 35 ]
then
        echo "青年"
elif [ "$1" -lt 65 ]
then
        echo "壮年"
else
        echo "老年"
fi

case,多条件分支

case "$1" in
1)
        echo "value is 1"
;;
2)
        echo "value is 2"
;;
3)
        echo "value is 3"
;;
*)
        echo "其他数字"
;;
esac

for循环

#!/bin/bash
sum=0
# 双小括号里面可以使用运算符<=
for (( i=0; i<=100; i++ ))
do
# 或者sum=$[ $sum+$i ],不过推荐下面这种写法
        sum=$(( sum + i ))
done
echo $sum

for in

#!/bin/bash
for os in linux windows macos
do
	echo $os
done

内部运算符{},

{}表示一个序列,从1到100可以表示为{1..100}

#!/bin/bash
for i in {1..100}
do
        sum=$((sum+i))
done
echo $sum

$*,$@

#!/bin/bash
echo '=======$*========'
for param in "$*"
do
        echo $param
done
echo '=======$@========'
for param in "$@"
do
        echo $param
done

运行结果:

[root@localhost scripts]# ./for4_test.sh 10 20 30
=======$*========
10 20 30
=======$@========
10
20
30

while循环

#!/bin/bash
i=0
sum=0
while [ $i -le 100 ]
do
	sum=$((sum + i))
	i=$((i+1))
# 可以用let,如let sum+=i
#   let i++
done
echo $sum

9.读取控制台输入

read 选项 参数

选项:

-p,提示信息

-t,等待时间,秒。不添加-t表示一直等待

参数:

变量:指定读取变量名

#!/bin/bash
read -t 10 -p "input a name:" name
echo "welcome, $name"

10.系统函数

date,

获取时间戳date +%s,date后加空格是要把+%s传递给date,不加空格表示date+%s是一个字符串

[root@localhost scripts]# cat sy_fun_test.sh
#!/bin/bash
filename="$1_log_$(date +%s)"
echo $filename


[root@localhost scripts]# ./sy_fun_test.sh file.sh
file.sh_log_1710361088

basename

获取文件名,basename [string/pathname][suffix]

至少有一个路径的/符号,只会截取/后面的内容。suffix表示要去掉的后缀名。

[root@localhost scripts]# basename /scripts/cmd_test.sh 
cmd_test.sh
[root@localhost scripts]# basename /abc/def/cmd_test.sh 
cmd_test.sh
[root@localhost scripts]# basename /abc/def/cmd_test.sh .sh
cmd_test

$0,获取当前文件名,带路径的,相对、绝对路径

[root@localhost scripts]# cat basename_test.sh 
#!/bin/bash
echo '======$0====='
echo "当前文件名:$(basename $0 .sh)"


[root@localhost scripts]# ./basename_test.sh 
======$0=====
当前文件名:basename_test

dirname

获取绝对路径,去掉文件名

[root@localhost scripts]# dirname /scripts/basename_test.sh 
/scripts
[root@localhost scripts]# cat basename_test.sh 
#!/bin/bash
echo '======$0====='
echo "当前文件名:$(basename $0 .sh)"
# cd先切换到脚本所在目录。pwd只会打印当前目录绝对路径。
echo "当前路径名:$(cd $(dirname $0); pwd)"



[root@localhost scripts]# ./basename_test.sh
======$0=====
当前文件名:basename_test
当前路径名:/scripts
[root@localhost scripts]# /scripts/basename_test.sh
======$0=====
当前文件名:basename_test
当前路径名:/scripts

11.自定义函数

语法

function 函数名(){

        //函数体

        return 返回值

}

[root@localhost scripts]# cat fn_test.sh 
#!/bin/bash
function add(){
	sum=$(($1 + $2))
	echo "the sum is $sum"	
}
read -p "input param1:" a
read -p "input param2:" b

add $a $b



# 运行结果
[root@localhost scripts]# ./fn_test.sh
input param1:11
input param2:22
the sum is 33

可以使用$?获取返回值,但是返回值只能是0~255

#!/bin/bash
function add(){
	sum=$(($1 + $2))
	echo $sum	
}
read -p "input param1:" a
read -p "input param2:" b

sum=$(add $a $b)
echo "the sum is $sum"
echo "the square of sum is $(($sum * $sum))"


# 结果
[root@localhost scripts]# ./fn_test.sh
input param1:1000
input param2:2000
the sum is 3000
the square of sum is 9000000

12.归档文件

需求:目录归档脚本,input一个目录名称,将目录下所有文件按天归档保存,并将归档日期附加在文档文件名上,放在根目录下(/archive)

归档命令:tar,-c归档,-z压缩文件

#!/bin/bash
# 判断输入参数个数
if [ $# != 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) # 使用 %Y 获取四位年份
# 归档文件名
file=archive_${dir_name}_$date.tar.gz # 修正了命令替换和变量引用
# 生成归档文件的路径
dest=/archive/$file

# 开始归档
tar -czf $dest $dir_path/$dir_name # 修正了变量名
# 判断归档是否成功
if [ $? -eq 0 ]
then
	echo "归档成功"
	echo "归档的文件为$dest"
else
	echo "归档失败"
fi

13.定时归档

crontab 命令:

  • crontab -l: 列出当前用户的 crontab 文件内容。
  • crontab -e: 编辑当前用户的 crontab 文件。
  • crontab -r: 删除当前用户的 crontab 文件。
[root@localhost scripts]# crontab -e

*/1 * * * * date >> /scripts/crontab_test.txt
0 2 * * * /scripts/delay_archive.sh /scripts


#分钟,小时,日,月,周,其中/1表示每隔1分钟
# 每天2点执行一次归档

14.正则

cat /etc/passwd | grep root

常用特殊字符:

^,匹配一行的开头

cat /etc/passwd | grep ^a

$,匹配一行的结束

cat /etc/passwd | grep a$

^$,匹配空字符

[root@localhost scripts]# cat delay_archive.sh | grep -n ^$
27:
38:
39:
40:

.,任意一个字符

cat /etc/passwd | grep r..t

*,前一个字符出现0次或多次

cat /etc/passwd | grep r.*t

[],范围

cat /etc/passwd | grep r[a-z]*t

\,转义,在如下实例中,只能用单引号',不能用双引号“,会被转义。

单引号会保留字符串内所有字符的字面值,所以grep '\$' 是正确的用法来匹配包含美元符号的行

[root@localhost scripts]# cat delay_archive.sh | grep '\$'
if [ $# != 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=/archive/$file
tar -czf $dest $dir_path/$dir_name
if [ $? -eq 0 ]
	echo "归档的文件为$dest"

匹配手机号

-E 选项用于启用扩展正则表达式(Extended Regular Expressions),这允许你使用更多的正则表达式功能,比如 +?{} 和 | 等

[root@localhost scripts]# echo "14747696666" | grep -E '^1[3-9][0-9]{9}$'
14747696666

15.cut文本处理工具

cut 选项参数 filename

选项说明
选项参数功能
-f列号,取第几列
-d分隔号,指定分隔号固定分隔,默认是\t
-c

[root@localhost scripts]# cut -d " " -f 1 custs_test.txt 
程
序
员
你
好



[root@localhost scripts]# cat /etc/passwd | grep bash$
root:x:0:0:root:/root:/bin/bash
www:x:1000:1000::/home/www:/bin/bash
[root@localhost scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 1,7
root:/bin/bash
www:/bin/bash

# 5-,表示6-7列,包括7
[root@localhost scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 5-
root:/root:/bin/bash
:/home/www:/bin/bash



# 裁剪ip
[root@localhost scripts]# ifconfig ens33 | grep netmask | cut -d " " -f 10
192.168.199.154

  • 39
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值