初识shell,变量,if,whil,for

一:初识shell

shell的中文名字叫”贝壳“ ,听这名字就知道shell是一个将系统接口及底层内核硬件封装好的解释型应用程序,shell有两种意思,一种是编译语言,一种是解释器,解释shell风格的解释器(可写脚本运行,可执行交互命令)

1.1 运行shell的两种方式

1、交互式环境

每敲一条立即执行一条
不能永久保存代码

2、把shell命令写入文件中,该文件称之为脚本文件

bash 脚本文件的路径
[root@localhost ~]# vim 2.sh    # 脚本文件里是完整的执行内容
bip=wwww.baidu.com
ping $bip
[root@localhost ~]# bash 2.sh
PING www.wshifen.com (45.113.192.101) 56(84) bytes of data.
64 bytes from 45.113.192.101 (45.113.192.101): icmp_seq=1 ttl=128 time=239 
------------------------------------------
[root@localhost ~]# chmod +x 2.txt
[root@localhost ~]# ./2.txt
# 将次文件添加一个可执行权限,相当于重新开了一个子进程运行
-------------------------------------------
# 运行shell脚本经历的三个阶段
(1)先启动bash解释器
(2)bash解释器会将脚本文件的内容从硬盘读入内存
(3)bash解释器会解释执行刚刚读入内存的代码,识别语法

三 变量

1.1 变量

”量“ 就是事物的状态,在计算机中,变量是一种读取内存的机制,是为了让计算机像人一样记录事物变换的状态,当然存不是目的,目地是为了取出来的时候方便;在定义好变量后,下次直接使用变量名即可。

使用

先定义,后使用

语法

变量名 赋值符 变量值
x     =     1

1.2 变量的作用域

交互式使用-----》自定义,仅在当前shell生效

[root@localhost ~]# x=1
[root@localhost ~]# echo $x   # $取变量值
1

环境变量-------》在当前shell及子shell生效

# export xxx 将变量定义父子继承使用,新开的窗口需要重新定义
[root@localhost ~]# x=111
[root@localhost ~]# export x    
[root@localhost ~]# bash 
[root@localhost ~]# echo $x
111
-------------------------------------------
# 添加系统开机自启的配置文件/etc/profile		
将 x=111 
  export x  
# 写到文件最下面,开机自启,注意:新开的子shell或者新开窗口及su无效

命令

export x # 设置变量名x父子继承
set      # 查看所有变量(包括自定变量和环境变量) 
env      # 查看环境变量
unset x  # 删除变量

1.3 引号对变量的影响

“”:软引用,解释中间的内容

‘’:硬引用,显示中间的内容

``:取中间命令的运行结果

[root@www ~]# name="egon"
[root@www ~]# echo "hello $name"
hello egon
[root@www ~]# echo 'hello $name'
hello $name
[root@www ~]# date +%F
2021-04-09
[root@www ~]# x=`date +%F`
[root@www ~]# touch $x.txt
2021-04-09.txt
[root@www ~]# y=$(date +%F)   # $()嵌套使用
[root@www ~]# touch ${y}.bak
[root@www ~]# ls
2021-04-09.bak  
[root@www ~]# tar czf `date +%F`.tar.gz /opt/
tar: Removing leading `/' from member names
[root@www ~]# ls
2021-04-09.tar.gz  

二:shell特殊字符·元字符

shell语法中的特殊字符,注意:元字符是解释器运行

  • `` 与$():取命令的结果

    [root@localhost ~]# echo `pwd`
    /root
    [root@localhost ~]# echo $(pwd)
    /root
    
    不一样的地方在于$()可以嵌套,而``不能嵌套
    [root@localhost ~]# echo $(ls $(find ./ -name "*.txt"))
    ./1a.txt ./1b.txt ./1c.txt ./1p.txt ./1q.txt ./1r.txt ./1s.txt ./1t.txt ./1.txt ./2021-04-09.txt ./2a.txt ./2b.txt ./2c.txt ./2.txt ./3a.txt ./3b.txt ./3c.txt ./3.txt .
    
  • ~家目录

  • .与…

  • !取反

    [root@localhost ~]# touch /test/{1.txt,2.txt,a.txt,aaa_bbb.txt}
    [root@localhost ~]# find /test ! -name 1.txt
    /test
    /test/2.txt
    /test/a.txt
    /test/aaa_bbb.txt
    [root@localhost ~]# ls /test/[!0-9].txt  # .txt前只有一个字符,但是非数字
    /test/a.txt
    [root@localhost ~]# ls /test/[^0-9].txt  # .txt前只有一个字符,但是非数字
    /test/a.txt
    
  • @无特殊$取变量值

  • #注释

  • $取变量值

    [root@localhost ~]# x=1
    [root@localhost ~]# echo $x
    1
    
  • %、-、+运算符

    # 数学运算
    # 1、bc是比较常用的linux计算工具了,而且支持浮点运算:
    [root@localhost ~]# res=`echo 1+1 | bc`
    [root@localhost ~]# echo $res
    2
    
    [root@localhost ~]# res=`echo 10 % 3 | bc`
    [root@localhost ~]# echo $res
    1
    
    [root@localhost ~]# res=`echo 1.2+1.3|bc`
    [root@localhost ~]# echo $res
    2.5
    
    [root@localhost ~]# res=`echo 5.0+3.0|bc`
    [root@localhost ~]# echo $res
    8.0
    
    [root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc`
    [root@localhost ~]# echo $res
    1.66
    
    [root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc`
    [root@localhost ~]# echo $res
    .83
    
    # 2、expr不支持浮点数计算。而且要注意数字与运算符中的空格
    [root@localhost ~]# res=`expr 5 / 3`  # 不支持浮点计算
    [root@localhost ~]# echo $res
    1
    
    [root@localhost ~]# res=`expr 1+1`  # 注意:要有空格
    [root@localhost ~]# echo $res
    1+1
    [root@localhost ~]# res=`expr 1 + 1`
    [root@localhost ~]# echo $res
    2
    
    # 3、$(()) 同expr,不支持浮点数运算
    [root@localhost ~]# echo $((1+1))
    2
    [root@localhost ~]# echo $((1.0+2.0))
    -bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0"#4、let 不支持浮点数运算,而且不支持直接输出,只能赋值
    [root@localhost ~]# let res=1+1
    [root@localhost ~]# echo $res
    2
    [root@localhost ~]# 
    [root@localhost ~]# let res=50/5
    [root@localhost ~]# echo $res
    10
    [root@localhost ~]# let c=1.3*3
    -bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3"
    
  • ^同!一样

  • *任意多个字符

    [root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt
    [root@localhost ~]# rm -rf *.txt
    [root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt a1c.txt
    [root@localhost ~]# ls *.txt
    1.txt  2.txt  a1c.txt  aaa.txt  aa.txt
    
  • ()在子shell中执行

    [root@localhost ~]# (x=1)
    [root@localhost ~]# echo $x
    
    应用
    [root@localhost ~]# (umask 066;touch a.txt)  # umask的设置只在子shell中有效
    [root@localhost ~]# ll a.txt 
    -rw-------. 1 root root 0 8月  13 15:22 a.txt
    [root@localhost ~]# touch b.txt
    [root@localhost ~]# ll b.txt 
    -rw-r--r--. 1 root root 0 8月  13 15:23 b.txt
    
  • _下划线:无特殊意义,可以用于名字的声明

  • =赋值,判断相等性

    [root@localhost ~]# [ 1 = 1 ]  # 条件1 = 1的左右两边必须有空格
    [root@localhost ~]# echo $?    # 判断上一条命令的结果是否为真,0=》true
    0
    
  • |管道:把一个进程的处理结果传递给另外一个进程

    [root@localhost ~]# ps aux | grep python
    
    xargs参数传递,把上一个命令的结果作为下一个命令的参数
    [root@localhost ~]# find /home/ -type d -name "test*" |xargs ls
    1.txt  2.txt  3.txt
    [root@localhost ~]# ls /home/test
    1.txt  2.txt  3.txt
    
  • \转义特殊字符

    [root@localhost ~]# mkdir a\ b.txt  # 虽然可以,但不推荐
    [root@localhost ~]# ll
    总用量 0
    drwxr-xr-x. 2 root root 6 8月  13 15:35 a b.txt
        
    
    [root@localhost ~]# echo $RMB  # 默认会当成变量
    
    [root@localhost ~]# echo '$RMB'  # 取消特殊意义
    $RMB
    [root@localhost ~]# echo \$RMB  # 取消特殊意义
    $RMB
    
  • []条件测试,后续会详细介绍

    [root@localhost ~]# name="egon"
    [root@localhost ~]# [ $name = "egon" ];echo $?
    0
    [root@localhost ~]# name="adf"
    [root@localhost ~]# [ $name = "egon" ];echo $?
    1
    
    [root@localhost ~]# [ -d /test ];echo $?
    
  • 引号

    ''  强引用(在单引号中都视为普通字符)
    " " 弱引用 (在双引号中保留变量)
    
    [root@localhost ~]# x=111
    [root@localhost ~]# echo "$x"
    111
    [root@localhost ~]# echo '$x'
    $x
    
  • ;与&&与||连接多条命令

    [root@localhost home]# gagaga;ls  # 不论前一条命令运行成功与否,都会执行后续命令
    bash: gagaga: 未找到命令...
    egon
    [root@localhost home]# gagaga && ls  # 只有前一条命令执行成功,才会执行后续命令
    bash: gagaga: 未找到命令...
            
    [root@localhost home]# ls /test || mkdir /test  # 前一条命令执行不成功才会执行后续命令
    0.txt  1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  7.txt  8.txt  9.txt
    
  • 引号

    ''  强引用(在单引号中都视为普通字符)
    " " 弱引用 (在双引号中保留变量)
    
    [root@localhost ~]# x=111
    [root@localhost ~]# echo "$x"
    111
    [root@localhost ~]# echo '$x'
    $x
    
  • ;与&&与||连接多条命令

    [root@localhost home]# gagaga;ls  # 不论前一条命令运行成功与否,都会执行后续命令
    bash: gagaga: 未找到命令...
    egon
    [root@localhost home]# gagaga && ls  # 只有前一条命令执行成功,才会执行后续命令
    bash: gagaga: 未找到命令...
            
    [root@localhost home]# ls /test || mkdir /test  # 前一条命令执行不成功才会执行后续命令
    0.txt  1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  7.txt  8.txt  9.txt
    
  • /路径分隔符

  • {}包含

    [root@localhost home]# touch /test/{0..9}.txt  # 当变量后面需要加上其他内容时将变量值加上{}例:echo ${x}RMB
    [root@localhost home]# ls /test/
    0.txt  1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  7.txt  8.txt  9.txt
    
  • &后台运行

    [root@localhost home]# echo "hello";sleep 3;echo "world" &
    
  • 重定向

    > >> 输出重定向
    < << 输入重定向
    
    > 覆盖  >> 追加
    [root@localhost home]# cat >> a.txt << EOF
    > 111
    > 222
    > 333
    > EOF
    
    0标准输入、1标准正确输出、2标准错误输出,&标准正确和错误输出
    [root@localhost home]# pwd 1>a.txt
    [root@localhost home]# cat a.txt 
    /home
    [root@localhost home]# gagag 2>a.txt
    [root@localhost home]# cat a.txt 
    bash: gagag: 未找到命令...
    [root@localhost home]# gagaga &>/dev/null
    
    < << 输入重定向
    [root@localhost ~]# mysql -uroot -p123 < bbs.sql
    [root@localhost home]# grep root < /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    
                            
    [root@localhost home]# dd if=/dev/zero of=/a.txt bs=1M count=10
    记录了10+0 的读入
    记录了10+0 的写出
    10485760字节(10 MB)已复制,0.024387 秒,430 MB/秒
    [root@localhost home]# dd </dev/zero >/b.txt bs=1M count=10
    记录了10+0 的读入
    记录了10+0 的写出
    10485760字节(10 MB)已复制,0.0202365 秒,518 MB/秒
    
    [root@localhost home]# ll /a.txt 
    -rw-r--r--. 1 root root 10485760 8月  13 16:02 /a.txt
    [root@localhost home]# ll /b.txt 
    -rw-r--r--. 1 root root 10485760 8月  13 16:03 /b.txt
    
  • ?任意一个字符

    [root@localhost ~]# ls ??.txt
    aa.txt
    [root@localhost ~]# ls a?c.txt
    a1c.txt
    [root@localhost ~]# rm -rf *txt
    
  • 范围中的任意一个字符 [12] [ac] [a-z] [0-9]

    [root@localhost ~]# touch a1c a2c axc aXc axd
    [root@localhost ~]# ls a?c
    a1c  a2c  axc  aXc
    [root@localhost ~]# ls a[1x]c
    a1c  axc
    [root@localhost ~]# ls a[a-z]c
    axc  aXc
    [root@localhost ~]# ls a[A-Z]c  # 不区分大小写
    axc  aXc
    [root@localhost ~]# ls a[x]c
    axc
    [root@localhost ~]# ls a[X]c
    aXc
    [root@localhost ~]# ls a[0-9]c
    a1c  a2c
    [root@localhost ~]# ls /dev/sd[a-z]*
    /dev/sda  /dev/sda1  /dev/sda2  /dev/sda3  /dev/sdb1
    

三:shell脚本使用补充

若脚本涉及到数据的读写操当,脚本中出现错误的脚本会对下面的运行数据产生很大的影响,这时我们可以添加相对应的命令应对。

#!/bin/bash         # 脚本文件一行普遍有的标识
set -o errexit      # 命令错误 
set -o nounset      # 变量错误
set -o pipefail     # 管道错误

echo 1
exho 2
asijiojp            # 错误命令
echo $y             # 没有定义变量
echo 3
echo 5
asfaf | echo 123    # 管道错误

简单判断:

&&:并且

|| :或者

[root@localhost ~]# name="egon"
[root@localhost ~]# password="123"
[root@localhost ~]# [ $name = "egon" ] && [ $password = "123" ]
[root@localhost ~]# echo $?
0   # 正确
[root@localhost ~]# [ $name = "egon" ] && [ $password = "1263" ]
[root@localhost ~]# echo $?
1   # 错误
[root@localhost ~]# [ $name = "egon" ] || [ $password = "1263" ]
[root@localhost ~]# echo $?
0

四:shell脚本复合命令

4.1 流程控制 if 判断

1、什么是if判断

依据条件的真假来决定是否做事

2、为何要有if判断

为了让计算机能够像人一样去做判断

3、如何用

if 条件1;then

​    代码1

​	代码2

​	代码3

elif 条件2;then

​    代码1

​	代码2

​	代码3

elif 条件3;then

​    代码1

​	代码2

​	代码3

.......

else

​    代码1

​	代码2

​	代码3

fi

案例1

#!/bin/bash

echo "start......"
read -p "请输入您的年龄: " age

if [ $age -eq 18 ];then
	echo "too young"
	echo "too young"
	echo "too young"
fi
echo "end......"

案例2

#!/bin/bash

echo "start......"
read -p "请输入您的年龄: " age

if [ $age -eq 18 ];then
	echo "too young"
else
	echo "too old"
fi
echo "end......"

案例3:

#!/bin/bash

read -p "请输入您的分数: " score

if [ $score -ge 90 ];then
    echo "优秀"
elif [ $score -ge 80 ] && [ $score -lt 90 ];then
    echo "良好"
elif [ $score -ge 70 ] && [ $score -lt 80 ];then
    echo "一般" 
else
	echo "很差"
fi

案例4:

#!/bin/bash

read -p "请输入您的分数: " score

if [ $score -ge 90 ];then
    echo "优秀"
elif [ $score -ge 80 ];then
    echo "良好"
elif [ $score -ge 70 ];then
    echo "一般" 
else
	echo "很差"
fi

案例5:

#!/bin/bash

read -p "输入用户名:" inp_user
read -p "输入密码:" inp_pwd

if [ $inp_user = "egon" ] && [ $inp_pwd = "123" ];then
	echo "登录成功"
else
	echo "用户名或者密码错误"
fi
	

二 流程控制之while循环

#!/bin/bash

while true
do
	echo 111
	echo 222
	echo 333
done

案例1

#!/bin/bash

while true
do
    read -p "输入用户名:" inp_user
    read -p "输入密码:" inp_pwd

    if [ $inp_user = "egon" ] && [ $inp_pwd = "123" ];then
        echo "登录成功"
    else
        echo "用户名或者密码错误"
    fi
done	

案例2:

#!/bin/bash

while true
do
    read -p "输入用户名:" inp_user
    read -p "输入密码:" inp_pwd

    if [ $inp_user = "egon" ] && [ $inp_pwd = "123" ];then
        echo "登录成功"
        break
    else
        echo "用户名或者密码错误"
    fi
done

案例3:

# 多行
while 条件
do
	命令1
	命令2
	命令3
done

# 一行
while 条件;do 命令1;命令2;命令3; done

while true;do ifconfig eth0;sleep 0.5;clear; done 

三 流程控制之for循环

案例1

for i in {1..3}
do
    echo ok1 $i
    echo ok2 $i
    echo ok3 $i
done

案例2

for x in "aaa" 2222 "ccc"
do
    echo $x
done

案例3

#!/bin/bash

for i in {2..254}
do
	(
    ping -c1 1.1.1.$i &>/dev/null
    if [ $? -eq 0 ];then
        echo "1.1.1.$i ok"
    else
    	echo "1.1.1.$i down"
    fi
    ) &
done
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值