目录
[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 echo$1 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$456789' \| grep ""
echo '123$456789' \| grep "\\" \表示转义
echo '123$456789' \| 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 白天 把时间填好 (默认)
注意事项:
-
case⾏尾必须为单词"in",每⼀个模式匹配必须以右括号")"结束。
-
双分号";;"表示命令序列结束,相当于java中的break。
-
最后的"*)"表示默认模式,相当于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