目录
[1. Linux提供的Shell解析器](#1. Linux提供的Shell解析器)
[2. bash和sh关系](#2. bash和sh关系)
[3. Centos默认的Shell解析器是bash](#3. Centos默认的Shell解析器是bash)
[1. 变量名的定义规则](#1. 变量名的定义规则)
[2. 等号周围没有空格](#2. 等号周围没有空格)
[3. 查看变量](#3. 查看变量)
[4. 删除变量](#4. 删除变量)
[5. 正确地定义数组](#5. 正确地定义数组)
[6. 将局部环境变量提升为全局](#6. 将局部环境变量提升为全局)
[7. 正确选择引号](#7. 正确选择引号)
[8. 特殊变量名](#8. 特殊变量名)
[1. 算术运算符](#1. 算术运算符)
[2. 逻辑运算符](#2. 逻辑运算符)
[3. 常用的特殊字符串](#3. 常用的特殊字符串)
[4. 正则表达式](#4. 正则表达式)
[5. 扩展的正则表达式](#5. 扩展的正则表达式)
[1. if](#1. if)
[2. case](#2. case)
[3. 循环](#3. 循环)
[3.1 for](#3.1 for)
[3.2 while循环](#3.2 while循环)
[3.3 until](#3.3 until)
[3.4 select循环与菜单](#3.4 select循环与菜单)
[五、read 读取控制台输⼊](#五、read 读取控制台输⼊)
一、介绍
Shell ⼀个命令解释器,它接收应⽤程序/⽤户命令,然后调⽤操作系统内核。
Shell是⼀个功能强⼤的编程语⾔,易编写、易调试、灵活性强。
1. Linux 提供的Shell解析器
cat /etc/shells
vim hello.sh
chmod u+x hello.sh 设置权限
2. bash 和sh关系
软连接
3. Centos 默认的Shell解析器是bash
echo $SHELL 环境变量
二、定义
1. 变量名的定义规则
(1)变量名称可以由字⺟、数字和下划线组成,但是不能以数字开头,环境变量名建议⼤写。
(2)等号两侧不能有空格
(3)在bash中,变量默认类型都是字符串类型,⽆法直接进⾏数值运算。
(4)变量的值如果有空格,需要使⽤双引号或单引号括起来。
2. 等号周围没有空格
username="小明"
echo $username
username="小 红"
username=小红
3. 查看变量
set 查看所有环境变量
4. 删除变量
unset username 删除变量username
5. 正确地定义数组
arr=("小旺财" "小猫猫" "小丫丫")
echo ${arr[1]} 查看下标为1的内容
echo ${arr[*]} 查看数组所有内容
6. 将局部环境变量提升为全局
export username 提升变量范围 (局部提升为全局)
7. 正确选择引号
(1)不加引号、单引号、双引号对纯字符串无影响,有空格要用引号
dog=金毛
dog='金毛'
dog="金毛"
echo $dog 输出金毛
(2)单引号 和双引号 的区别:
⼀对单引号内的字符串将始终被解释为它的本身。
yy='dog 是一个小狗狗' 不解析 显示$dog
yy="dog 是一个小狗狗" 对解析 显示金毛
(3)反引号
kk=`ls` 或 kk=$(ls) 将命令的结果保存到变量中
echo $kk
8. 特殊变量名
vim demo2.sh echo 0 echo1 echo $2
sh demo2.sh a b c 传参a、b、c 显示demo2.sh a b
$n:n为数字(0为脚本名称,1-9参数)
$#:获取所有输⼊参数个数,常⽤于循环。
\*:这个变量代表命令⾏中所有的参数,*把所有的参数看成⼀个整体。
@:这个变量也代表命令⾏中所有的参数,不过@把每个参数区分对待。
$?:最后⼀次执⾏的命令的返回状态。如果这个变量的值为0,证明上⼀个命令正确执⾏;如果这个变量的值为⾮0(具体是哪个数,由命令⾃⼰来决定),则证明上⼀个命令执⾏不正确了。)
echo $# (获取所有输⼊参数个数)
echo $? 查看上一次命令或者脚本的执行状态的结果,如果是0,表示正确,如果是非0,表示错误
三、运算符
1. 算术运算符
echo ((3+2)) 或 echo [10+20]
expr 3 + 2 加空格
\* 乘法用转义字符\
expr 3 \* 2
2. 逻辑运算符
格式:[ 条件 ]
注意 :[] ⾥⾯前后必须要有空格
(1)字符串比较
9 -lt 10 \] 9\<10 echo $? 显示0,正确 -lt ⼩于(less than) -le ⼩于等于(less equal) -eq 等于(equal) -gt ⼤于(greater than) -ge ⼤于等于(greater equal) -ne 不等于(Not equal) (2)**文件权限判断** > \[ -r demo1.sh \] 验证demo1.sh有没有读权限 > > echo $? 显示0,有读权限 > > \[ -x demo1.sh \] 验证demo1.sh有没有执行权限 **(3)多条件判断** > \[ 9 -lt 10 \] \&\& echo 对 正确会输出对 > > \[ 9 -gt 10 \] \&\& echo 对 错误不会输出对 #### **3.** **常用的特殊字符串** (1)\^匹配⼀⾏的开头,如下,会匹配/etc/passwd中以root开头的⾏ grep "\^root" /etc/passwd (2)$匹配⼀⾏的结尾,如下,会匹配出/etc/passwd中以bash结尾的⾏ grep "bash$" /etc/passwd (3).匹配⼀个任意字符 grep "r..t" /etc/passwd (4)\*不单独使⽤,他和上⼀个字符连⽤,表示匹配上⼀个字符0次或多次 grep "r\*" /etc/passwd #### **4.** **正则表达式** 正则表达式通常被⽤来检索、 替换那些符合某个模式的⽂本。 echo "t1234567" \| grep "\[0-9\]" 1234567标红 echo "t123p1234567" \| grep "\[0-9\]\[3,6\]" 23 23 56 标红 echo '123$456$789' \| grep "$" echo '123$456$789' \| grep "\\$" \\表示转义 echo '123$456$789' \| grep "\\\\$" 找出所有包含'$'的⾏ #### **5.** **扩展的正则表达式** echo '1233333-45-6755668' \| grep -E "\[0-9\]{2,3}" 0-9数字,出现2-3次标红(尽量满足多的) ### **四、条件选择、判断** #### **1. if** ```bash age=$1 if [ $age -le 16 ];then echo "他还是个孩子" else echo "他是个大人" fi ``` ```bash if [ $1 -le 16 ];then echo "他还是个孩子" elif [ $1 -le 24 ] && [ $1 -gt 18 ];then echo "他是个年轻人,不能太气盛" else echo "他是个大人" fi ``` > sh demo3.sh 13 他还是个孩子 > > sh demo3.sh 20 他是个年轻人,不能太气盛 > > sh demo3.sh 26 他是个大人 **ctrl+q解锁** #### **2. case** ```bash case $1 in "上午") echo "火锅" echo "烤肉" ;; "中午") echo "三碗扯面" echo "六个纯瘦夹馍" ;; "晚上") echo "燕窝莲子羹" echo "牛奶" ;; *) echo "把时间填好" esac ``` > sh demo4.sh 上午 火锅 烤肉 > > sh demo4.sh 中午 三碗扯面 六个纯瘦夹馍 > > sh demo4.sh 晚上 燕窝莲子羹 牛奶 > > sh demo4.sh 白天 把时间填好 (默认) **注意事项**: 1) case⾏尾必须为单词"in",每⼀个模式匹配必须以右括号")"结束。 2) 双分号";;"表示命令序列结束,相当于java中的break。 3) 最后的"\*)"表示默认模式,相当于java中的default。 #### **3.** **循环** ##### **3.1 for** ```bash s=0 for((i=0; i<=100;i++)) do s=$[$s+$i] done echo $s ``` sh demo05.sh 输出5050 do相当于{ , done相当于} ```bash for j in $* do echo $j done for j in $@ do echo $j done ``` sh demo6.sh aa bb cc 输出 aa bb cc aa bb cc # $@ 最终会被""解析为一个数组,每个元素都是传入的参数 ```bash for j in "$@" do echo $j done ``` # $\* 最终会被""解析为一个连续的字符串,只有一个元素 ```bash for j in "$*" do echo $j done ``` sh demo6.sh aa bb cc 输出 aa bb cc aa、bb、cc ##### **3.2 while循环** ```bash num=$1 s=0 while [ $num -ge 0 ] do s=$[$num+$s] num=$[$num-1] done echo $s ``` ##### **3.3 until** 进⼊条件:循环条件为false ;退出条件:循环条件为true;刚好和while相反,所以不常⽤,⽤while就⾏。 ```bash num=$1 s=0 until [ $num -eq 0 ] do s=$[$num+$s] num=$[$num-1] done echo $s ``` ##### **3.4 select循环与菜单** ```bash PS3="请输⼊你要选择的序号: " select menu in ⽶饭 扯⾯ 包⼦ 稀饭 退出 do case $REPLY in 1|4) #米饭或稀饭s echo "$menu 价格是 15" ;; 2|3) #扯面或包子 echo "$menu 价格是 20" ;; 5) # break ;; *) #默认 echo "请你好好选" esac done ``` **PS3 是 select 的提示符**,**⾃动⽣成菜单**,选择5 break 退出循环  ### **五、read 读取控制台输** **⼊** read(选项)(参数) 选项: -p:指定读取值时的提示符; -t:指定读取值时等待的时间(秒)。 > read -p "请输入第一个数" num1 > > read -p "请输入第二个数" num2 > > echo "$num1 加上 $num2 的结果是 $\[$num1+$num2\]" > > read -t 10 -p "请输入第一个数" num1 #10秒钟输入第一个数 > > read -t 10 -p "请输入第二个数" num2 > > echo "$num1 加上 $num2 的结果是 $\[$num1+$num2\]" ### 六、⾃定义函数 ```bash function func1() { read -p "请输入第一个数" num1 read -p "请输入第二个数" num2 echo "$num1 加上 $num2 的结果是 $[$num1+$num2]" } func1 #调用 ``` ### **七、练习** 编写⼀个函数来计算输⼊的是不是⼀个**质数** ```bash function func1() { read -p "请输入一个数" num1 is_prime=true for ((i=2; i*i<=$num1; i++)) #sprt(num1) do if [ $(($num1%i)) -eq 0 ]; then is_prime=false break fi done if [ $is_prime = true ]; then echo "$num1 是质数" else echo "$num1 不是质数" fi } func1 ``` ```bash #!/bin/bash function func1() { read -p "请输入一个数" num1 is_prime=true for ((i=2; i*i<=$num1; i++)) do if [ $(($num1%i)) -eq 0 ]; then is_prime=false break fi done if [ $is_prime = true ]; then echo "$num1 是质数" else echo "$num1 不是质数" fi } while true; do echo "请选择操作:" echo "1. 检查一个数是否为质数" echo "2. 退出程序" read -p "请输入选项编号:" choice case $choice in 1) func1 ;; 2) echo "退出程序" exit 0 ;; *) echo "无效的选项,请重新选择。" ;; esac done ```