shell学习——最全版(持续更新)

Shell学习

概述

定义

shell脚本就是将完成一个任务的所有命令按照执行的先后顺序,自伤而下写入到一个文件中,然后给予执行权限

  • 给予执行文件授权
chmod 700 test.sh# 最好不用设置777,777十分危险

语法规范

  1. 名字要有意义

  2. 建议你使用.sh结尾

  3. shell开头必须指明脚本运行的环境

    # 指明解释器
    #! /bin/bash 
    
    #描述写清楚
    #Author:
    #Created:
    #Release:
    #Script description:
    
    # 脚本组成
    # 1. 解释环境
    ##或者使用python的环境 #!/usr/bin/env python
    # 2. 注释说明
    # 3. 执行代码
    
  4. 运行脚本

    • 给予权限

       chmod 700 test.sh# 最好不用设置777,777十分危险
      
    • 解释器直接运行,不需要给予权限

      bash test.sh
      
  5. 特殊符号

    !!		执行上一次命令
    $		变量中取值
    *		匹配所有
    ''		单引号不解释变量
    $?		判断上一条命令是否执行返回为真就是0,假为1,不成功为2
    ` `   里面放入命令,表示先执行其中的命令
    
  6. 数学运算

    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 1 + 2
    3
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 1 - 2
    -1
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 3 \* 2
    6
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 10 / 5
    2
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 10 % 3
    1
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# expr 10 /5
    expr: syntax error: unexpected argument “/5”
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# echo $?
    2
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# echo 10 % 3; echo $?
    10 % 3
    0 
    ## 双括号加$还能做运算
    [root@iZ2zedjlje7b8m5cqfq666Z ~]# echo $((100%7))
    2
    

语法

格式化输出

一个程序需要有0个或者以上的输入,一个或者更多的输出

echo命令
[root@iZ2zedjlje7b8m5cqfq666Z ~]# echo "hhhhh"
hhhhh
[root@iZ2zedjlje7b8m5cqfq666Z ~]# echo -n "hhhhhh"
hhhhhh[root@iZ2zedjlje7b8m5cqfq666Z ~]# 
[root@iZ2zedjlje7b8m5cqfq666Z ~]# echo -n "date is "; date 
date is 2021年 08月 20日 星期五 16:53:25 CST
#!/usr/bin/bash
  
# 简易倒计时
for time in `seq 9 -1 0`; do
        echo -n -e "\b$time"##-e代表转义字符,-n表示不换行
        sleep 1
done
echo

程序交互

######test.sh
#!/usr/bin/bash
  
# 登陆注册案例
echo -n "Login: " #-n表示不换行
read acc
echo -n "Passwd: "
read -s -t50 -n6 -pnull pw #-s表示不显示密码,-t50表示50s内不输入自动跳过,-n6表示最多输入6位数,-pnull表示默认是null
echo
echo "你输入的账号是: $acc      密码是:$pw"
######结果
[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
Login: 1234
Passwd: null
你输入的账号是: 1234	密码是:123423

你还可以使用

read -p "Login: " acc 

代替:

echo -n "Login: " #-n表示不换行
read acc

两个命令等价

变量

  1. 变量格式

    变量名=值

  2. 变量使用

    NAME="zhangsan"
    unset NAME # 取消变量
    export NAME # 设置全局变量
    

数组

特性
#!/usr/bin/bash
  
# 数组案例
ARRAY=('a' 'b' 'c' 'd' 'e')
echo ${ARRAY[3]}
ARRAY[3]='D'
echo ${ARRAY[3]}
echo ${ARRAY[@]} # 打印数组中所有的元素
echo ${#ARRAY[@]} # 打印数组中元素的个数
echo ${!ARRAY[@]} # 打印数组中元素的索引
echo ${ARRAY[@]:2} #从索引2开始,打印数组
echo ${ARRAY[@]:1:2} #从索引1开始,访问两个元素

输出结果

d
D
a b c D e
5
0 1 2 3 4
c D e
b c
关联数组
#声明关联数组
declare -A array1
declare -A array2
array1[name]='zhangsan'
array1[age]=19

echo ${array1[name]}

array2=([name]='lisi' [age]=20)
echo ${array2[name]}

输出结果

zhangsan
lisi

数据比较运算

数学比较运算
符号全称
-eqequal
-gegreater than or equal
-gtgreat than
-leless than or equal
-ltless than
-nenot equal
文件比较运算
符号解释
-ddocument ,判断目录是否存在
-ffile,判断文件是否存在
-e判断文件或者目录是否存在
-r|-w|-x判断文件存在且是否可读|可写|可执行
-s判断文件中存在是否为空(不为空是true)
-O检查文件存在且是否被拥有
-G检查文件存在且是否被当前组拥有

这其中全在test命令中,可以用man test命令查看

字符串比较运算
符号解释
==判断是否等于
!=判断是否不等于
-n判断字符串的长度是否大于0
-z检查字符串长度是否为0

if语句

#if语句
#没有/tmp/abc目录就创建

if [ ! -d /tmp/abc ]
then
        mkdir -v /tmp/abc # -v表示显示创建信息
        echo "successfully created /tmp/abc"
else
				echo "/tmp/abc already exist"
fi

输出结果:

[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
mkdir: 已创建目录 '/tmp/abc'
successfully created /tmp/abc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
/tmp/abc already exist
if高级运用
#if语句
# if语句高级运用
if (( 100%3+6>9  )) #if双括号直接加入数学表达式
 then
        echo "yes"
 else
        echo "no"
fi

for i in r1 r2 r3 aaa bbb ccc r4
do
 if [[ $i == r* ]] #用双中括号判断字符串是否匹配此为以r开头的字符
    then
            echo $i
 fi
done

输出结果

[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
no
r1
r2
r3
r4

还可以使用elif来控制判断条件

for语句

seq是数数命令 seq n k m ,从n开始,每次加k,一直到m,k可以省略,默认是1

两种写法:

# for语句两种写法
echo "第一种写法"
for i in Hava a nice day
do
        echo -n  "$i "
done

echo -e "\n第二种写法"
for (( i=0;i<10;i++ ))
do
        echo -n "$i "
done
echo

执行结果:

第一种写法
Hava a nice day 
第二种写法
0 1 2 3 4 5 6 7 8 9

还可以使用breakcontinue来控制循环

break高级用法

for (( ; ; )); do
    echo "这是最外层循环"
    for (( ; ; )); do
        echo "这是中层循环"
        for (( ; ; )); do
        echo "这是里层循环"
        break 1 # 跳出里层循环 
        break 2 # 跳出中层循环
        break 3 # 跳出外层循环
        done
    done
done

输出结果:

### break 1
这是里层循环
这是中层循环
这是里层循环
这是中层循环
这是里层循环
这是中层循环
这是里层循环
这是中层循环
这是里层循环
.....

### break2
这是最外层循环
这是中层循环
这是里层循环
这是最外层循环
这是中层循环
这是里层循环
这是最外层循环
这是中层循环
这是里层循环
这是最外层循环
这是中层循环
这是里层循环
这是最外层循环
....

### break 3
这是最外层循环
这是中层循环
这是里层循环

while循环

# while循环语句制造99乘法表
n=1
while [ $n -lt 10 ]; do
    for ((i = 1; i <= n; i++)); do
        echo -n "$i * $n = $((i * n))  "
    done
    echo
    n=$((n + 1))
done

# 使用while遍历文件内容
j=1
while read i; do
    echo "第$j 行: $i"
    j=$((j + 1))
done <$1

# 使用while读出文件中的列,IFS指定默认的列分隔符
IFS=$":" # 指定冒号分隔符
while read f1 f2 f3 f4 f5 f6 f7; do
    echo "$f1   $f2   $f3"
done < /etc/passwd

输出结果

#结果一
[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
1 * 1 = 1  
1 * 2 = 2  2 * 2 = 4  
1 * 3 = 3  2 * 3 = 6  3 * 3 = 9  
1 * 4 = 4  2 * 4 = 8  3 * 4 = 12  4 * 4 = 16  
1 * 5 = 5  2 * 5 = 10  3 * 5 = 15  4 * 5 = 20  5 * 5 = 25  
1 * 6 = 6  2 * 6 = 12  3 * 6 = 18  4 * 6 = 24  5 * 6 = 30  6 * 6 = 36  
1 * 7 = 7  2 * 7 = 14  3 * 7 = 21  4 * 7 = 28  5 * 7 = 35  6 * 7 = 42  7 * 7 = 49  
1 * 8 = 8  2 * 8 = 16  3 * 8 = 24  4 * 8 = 32  5 * 8 = 40  6 * 8 = 48  7 * 8 = 56  8 * 8 = 64  
1 * 9 = 9  2 * 9 = 18  3 * 9 = 27  4 * 9 = 36  5 * 9 = 45  6 * 9 = 54  7 * 9 = 63  8 * 9 = 72  9 * 9 = 81

#结果二
[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh /etc/passwd
第1 行: root:x:0:0:root:/root:/bin/bash
第2 行: bin:x:1:1:bin:/bin:/sbin/nologin
第3 行: daemon:x:2:2:daemon:/sbin:/sbin/nologin
第4 行: adm:x:3:4:adm:/var/adm:/sbin/nologin
第5 行: lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
第6 行: sync:x:5:0:sync:/sbin:/bin/sync
第7 行: shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
第8 行: halt:x:7:0:halt:/sbin:/sbin/halt
第9 行: mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
第10 行: operator:x:11:0:operator:/root:/sbin/nologin
第11 行: games:x:12:100:games:/usr/games:/sbin/nologin
第12 行: ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
....


#结果三
[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
root   x   0
bin   x   1
daemon   x   2
adm   x   3
lp   x   4
sync   x   5
shutdown   x   6
halt   x   7
mail   x   8
operator   x   11
games   x   12
ftp   x   14
nobody   x   65534
dbus   x   81
systemd-coredump   x   999
systemd-resolve   x   193
tss   x   59
polkitd   x   998
unbound   x   997
libstoragemgmt   x   996
cockpit-ws   x   995
setroubleshoot   x   994
sssd   x   993
insights   x   992

until语句

和while相反,条件为假开始循环

i=1
until [ $i -gt 10 ]; do
    echo "$i"
    i=$((i+1))
done

#输出结果
1
2
3
4
5
6
7
8
9
10

case

while :; do
    read -p "请输入数字:" i
    case $i in
    1 | 2 | 3)
        echo "你选择了一个小于4的数"
        ;;
    4 | 5 | 6)
        echo "你选择了一个4-6之间的数"
        ;;
    7 | 8 | 9)
        echo "你选择了一个大于7的数"
        ;;
    *)
        echo "你选择了一个很大的数,我要退出了"
        exit 0
        ;;
    esac
done

输出结果:

[root@iZ2zedjlje7b8m5cqfq666Z ~]# ./test.sh 
请输入数字:1
你选择了一个小于4的数
请输入数字:2
你选择了一个小于4的数
请输入数字:5
你选择了一个4-6之间的数
请输入数字:4
你选择了一个4-6之间的数
请输入数字:6
你选择了一个4-6之间的数
请输入数字:8
你选择了一个大于7的数
请输入数字:9
你选择了一个大于7的数
请输入数字:10
你选择了一个很大的数,我要退出了
符号解释
$0脚本名字
$*脚本参数
$#传参数量
$$脚本执行进程号
$_最后执行命令
$N第n个参数

函数

#函数两种方法的使用
#第一种定义方法
function start {
    echo "Starting....          [ok]"
}
#第二种定义方法
stop() {
    echo "Stopping....          [ok]"
}

#函数不会自己执行,除非你调用
start
start
stop
stop

输出结果:

Starting....          [ok]
Starting....          [ok]
Stopping....          [ok]
Stopping....          [ok]

Nginx启动管理脚本

sh -x 

正则表达式

特殊字符

定位符使用技巧:同时锚定开头和结尾,做精确匹配;单一锚定开头和结尾,做到模糊匹配

定位符说明
^锚定开头 ^a是以a开头 默认锚定一个字符
$锚定结尾 $a是以a结尾 默认锚定一个字符

测试案例:

[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ac$" file
ac
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a" file
a
abc
ac
abbbc
aaaaccc
abcdfs
assd
assskslss
askdsk
abbbbc
abbbc
asjhsjhsc
### egrep 和 grep -E 一样
匹配符
匹配符说明
.匹配除回车以外的任意字符
()字符串分组
[]定义字符类,匹配括号中的一个字符
[^]表示否定括号中出现的字符,取反
\转义字符
|

测试案例:

[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a.c$" file
abc
aic
agc
a2c
a_c
aZc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a[0-9]c$" file
a2c
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a[^0-9]c$" file
abc
aic
agc
a_c
aZc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a[a-z]c$" file
abc
aic
agc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a[a-Z]c$" file
abc
aic
agc
aZc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a[^a-Z]c$" file
a2c
a_c
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a\*c$" file
a*c
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^a*c$" file
ac
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^(a|b)c$" file
ac
bc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^(a|b).c$" file
abc
bbc
aic
agc
a2c
a_c
aZc
bac
a*c
限定符
限定符说明
*表示该字符不出现或者多次出现
?表示该字符出现一次或者不出现
+表示前面字符出现一次或者多次,但必须出现一次
{n,m}表示该字符最少n次,最多m次
{m}表示该字符正好出现了m次

测试案例:

[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ab*c$" file
abc
ac
abbbc
abbbbc
abbbc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ab?c$" file
abc
ac
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ab+c$" file
abc
abbbc
abbbbc
abbbc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ab{3}c$" file
abbbc
abbbc
[root@iZ2zedjlje7b8m5cqfq666Z ~]# egrep "^ab{1,3}c$" file
abc
abbbc
abbbc
元字符
字符说明
[a-z]字符范围。匹配指定范围内的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\d匹配一个数字字符。等价于 [0-9]。
\D匹配一个非数字字符。等价于 [ ^ 0-9]。
\w匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
\W匹配任何非单词字符。等价于 ‘[ ^ A-Za-z0-9_]’。

sed命令

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值