shell 是一种脚本语言。
脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译)
shell 既是应用程序 又是一种脚本语言(应用程序 解析 脚本语言)
#!/bin/bash
# 第一行主要用于指定解释器(包括:bin/sh、bin/bash、usr/bin/sh、usr/bin/bash)
# 我是单行注释
# 执行脚本的方式有三种:sh test.sh、. test.sh、source test.sh
# 决定路径执行:./test.sh,这种执行方式需要可执行权限,给脚本添加可执行权限:chmod 777 test.sh
# ./test.sh 方式执行需要指定解释器
# 三种变量:局部变量、环境变量、shell变量
# 变量:
name="hello" # 等号两边不能有空格
echo ${name} # 输出普通变量
function test() {
local name="test hello" # 局部变量用local关键字修饰,local必须在函数中使用
echo ${name}
}
name="only_read"
readonly name # readonly修饰符,修饰只读变量
echo $name # 或者 ${name}
name1="name1"
unset name1 # 删除变量,不能删除只读变量,删除后的变量无法被访问
# 单引号和双引号字符串的区别
name2='name2' # 单引号字符串,字符串内不能转义,不能包含变量
name3="name3\"${name2}" # 双引号字符串,字符串内可以有转义,也可以包含变量
echo ${name3}
# 字符串拼接
str1="1""2""3"'4''5' # 字符串字面量拼接
str2='6'
str3=${str1}${str2} # 字符串变量拼接
echo $str3
str4=`date`'==='$str3 # 命令拼接
echo $str4
# 获取字符串长度的5种方式
echo "hello" | wc -L # 1、wc -L 获取当前行的长度
expr length ${str3} # 2、使用expr length可以获取string的长度
echo "abc" |awk -F "" '{print NF}' # 3、awk获取域的个数
echo "Alex" |awk '{print length($0)}' # 4、通过awk+length的方式获取字符串长度
str5=Alex
echo ${#str5} # 通5、过 ${#str5} 的方式获取字符串长度
# 提取字符串
str6=123456789.jpg
echo ${str6##*56} # 从左向右截取最后一个string后的字符串 ,输出:789.jpg
echo ${str6#*56} # 左向右截取第一个string后的字符串,输出:789.jpg
echo ${str6%%56*} # 从右向左截取最后一个string后的字符串,输出:1234
echo ${str6%56*} # 从右向左截取第一个string后的字符串,输出:1234
echo ${str6:1:3} # 截取字符串,输出:234
# 数组
echo "====数组==== 数组越界不会报错"
array=(1 2 3 4 5 6)
echo ${array} # 输出数组,默认输出角标为0的数据
echo ${array[5]} # 输出数组角标为5的数据
array[0]=7 # 数组赋值
echo ${array} # 输出数组
array=([0]=0 [1]=1 [2]=2 [3]=3 [4]=4 [5]=5 [6]=6) # 数组初始化或赋值
echo ${array[6]} # 输出数组角标为6的数据
for((i=0;i<7;i++)) # for循环遍历数组
do
echo "array[$i]=${array[$i]}"
done
echo ${array[*]} # 输出整个数组
echo "a len: ${#array[*]}" # 输出数组的长度
a=(1 2 3 4 5 6)
b=("hello" "zhaixue.cc")
c=(${a[*]} ${b[*]}) # 数组拼接
echo ${c[*]} # 输出整个数组
echo "c length: ${#c[*]}" # 输出:c length: 8
unset c[6] # 删除数组中的元素
echo "c length: ${#c[*]}" # 输出:c length: 7
# 参数传递
# $0 代表执行的文件名
# $1 代表传入的第1个参数
# $n 代表传入的第n个参数
# $# 参数个数
# $* 以一个单字符串显示所有向脚本传递的参数。
# $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
# $$ 脚本运行的当前进程号
# $! 后台运行的最后一个进程的ID
# $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
# 运算符 需注意:条件表法式需要放在方括号之间,并且要有空格。使用expr进行计算时需要使用反引号。
# 加法 expr $a + $b
# 减法 expr $a - $b
# 乘法 expr $a \* $b
# 除法 expr $b / $a
# 取余 expr $b % $a
# 赋值 a=$b
# 相等 [ $a == $b ]
# 不相等 [ $a != $b ]
a=10
b=20
c=`expr $a + $b` # 加法运算
echo "a + b : $c"
# 关系运算符
# 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
# 关系用 [] 来表示,
echo "====关系运算符===="
a=1
b=2
# 检测两个数是否相等 [ $a -eq $b ] -eq
if [ $a == $b ]
then
echo "a和b相等"
else
echo "a和b不相等"
fi
# 或者
if [ $a -eq $b ]
then
echo "a和b相等"
else
echo "a和b不相等"
fi
# 检测两个数是否不相等 [ $a -ne $b ] -ne
if [ $a != $b ]
then
echo "a和b不相等"
else
echo "a和b相等"
fi
# 或者
if [ $a -ne $b ]
then
echo "a和b不相等"
else
echo "a和b相等"
fi
# 检测左边的数是否大于右边的 [ $a -gt $b ] -gt
if [ $a -gt $b ]
then
echo "a大于b"
else
echo "a等于b或a小于b"
fi
# 检测左边的数是否小于右边的 [ $a -lt $b ] -lt
if [ $a -lt $b ]
then
echo "a小于b"
else
echo "a等于b或a大于b"
fi
# 检测左边的数是否大于等于右边的 [ $a -ge $b ] -ge
if [ $a -ge $b ]
then
echo "a大于等于b"
else
echo "a小于b"
fi
# 检测左边的数是否小于等于右边的 [ $a -le $b ] -le
if [ $a -le $b ]
then
echo "a小于等于b"
else
echo "a大于b"
fi
# 布尔运算符
# 非运算 [ ! false ] !
# 或运算 [ $a -lt 20 -o $b -gt 100 ] -o
# 与运算 [ $a -lt 20 -a $b -gt 100 ] -a
# 逻辑运算符
# 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] &&
# 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] ||
# 布尔运算符和逻辑运算符的区别:
# 语法上,逻辑运算需要双括弧,布尔运算只需要单大括弧功能上,逻辑运算具有特殊的短路功能,
# 即是在AND运算中第一个表达式为false时则不执行第二个表达式,
# 在OR运算中第一个表达式为true时不执行第二个表达式。
# 字符串运算符
# 检测两个字符串是否相等 [ $a = $b ] =
# 检测两个字符串是否不相等 [ $a != $b ] !=
# 检测字符串长度是否为0 [ -z $a ] -z
# 检测字符串长度是否不为 0 [ -n “$a” ] -n
# 检测字符串是否为空 [ $a ] $
# 文件测试运算符
# 检测文件是否是块设备文件 [ -b $file ] -b file
# 检测文件是否是字符设备文件 [ -c $file ] -c file
# 检测文件是否是目录 [ -d $file ] -d file
# 检测文件是否是普通文件(既不是目录,也不是设备文件) [ -f $file ] 返回 true -f file
# 检测文件是否设置了 SGID 位 [ -g $file ] -g file
# 检测文件是否设置了粘着位(Sticky Bit) [ -k $file ] -k file
# 检测文件是否是有名管道 [ -p $file ] -p file
# 检测文件是否设置了 SUID 位 [ -u $file ] -u file
# 检测文件是否可读 [ -r $file ] -r file
# 检测文件是否可写 [ -w $file ] -w file
# 检测文件是否可执行 [ -x $file ] -x file
# 检测文件是否为空(文件大小是否大于0) [ -s $file ] -s file
# 检测文件(包括目录)是否存在 [ -e $file ] -e file
file="/home/westos/Desktop/textcpp/test.sh"
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
# 运算指令
# (( )) 可以直接使用双圆括弧计算其中的内容,如((var=a+b))
# let 在计算表达式的时候我们可以直接使用let,如let var=a+b。
# expr
var=`expr a+b`
echo $var
# bc计算器 :bc计算器支持shell中的小数进行运算,并且可以交互式或者非交互式的使用
var=$(echo "(1.1+2.1)"|bc)
echo $var
# $[]: 计算中括弧中的内容,如echo $[1+2]
# 控制语句
a=1
b=1
# if-fi
if [ $a -eq $b ]
then
echo "a等于b"
fi
# if-else-fi
if [ $a -eq $b ]
then
echo "a等于b"
else
echo "a不等于b"
fi
# if else-if else
if [ $a -gt $b ]
then
echo "a大于b"
elif [ $a -lt $b ]
then
echo "a小于b"
else
echo "a等于b"
fi
# for循环
for a in 1 5 3 4
do
echo ${a} # 一次输出 1 5 3 4
done
array=(1 2 3 4 5 6 7 8)
for((i=0;i<8;i++)) # for循环遍历数组
do
echo "array[$i]=${array[$i]}"
done
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
# while循环
a=1
b=4
while [ $a -lt $b ]
do
echo "${a}"
let a++
done
# 无限循环
# for (( ; ; ))
# do
# echo 111
# done
# while true
# do
# echo 222
# done
# until循环
# until 循环执行一系列命令直至条件为 true 时停止
a=1
until [ $a -gt 3 ]
do
echo "until循环:$a"
let a++
done
# 跳出循环
var=1
while(( $var < 5 ))
do
if(( $var>3 ))
then
echo "break跳出循环"
break
fi
echo "$var"
var=`expr $var + 1`
done
var=1
while(( $var < 5 ))
do
echo "$var"
var=`expr $var + 1`
if [ $var -gt 2 ] && [ $var -lt 4 ]
then
echo "continue跳出循环:$var"
continue
elif [ $var -eq 4 ]
then
echo "break跳出循环"
break
fi
done
# case-esac多选择语句
echo "====case-esac多选择语句===="
var=100
case $var in # 分支语句开始
10)
echo "输出10"
;; # 相当于break
100)
echo "输出100"
;; # 相当于break
esac # 分支语句结束
# select-in语句
# select in是shell中独有的一种循环,非常适合终端的交互场景,它可以显示出带编号的菜单,
# 用户输入不同编号就可以选择不同的菜单,并执行不同的功能
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other";
do
echo "You have selected $var"
break;
done
# 函数
function funName() { # function可以省略
echo "执行了funName函数"
}
funName # 执行函数
funWithParam(){
echo "第一个参数为 $1 !"
echo "第十个参数为 ${10} !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73 # 执行函数并传递参数
# 重定向
#一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
# 1、标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
# 2、标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
# 3、标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
# > 标准输出覆盖重定向:将命令的输出重定向输出到其他文件中
# >> 标准输出追加重定向:将命令的输出重定向输出到其他文件中
# >& 标识输出重定向:将一个标识的输出重定向到另一个标识的输入
# < 标准输入重定向:命令将从指定文件中读取输入而不是从键盘输入
# | 管道符,从一个命令中读取输出并作为另一个命令的输入
# 输入重定向
# 可以让命令从文件中获取,这样本来的命令需要从标准输入stdin中获取,
# 转换为从我们的指定文件中获取。这样本来需要从键盘输入的命令就会转移到文件读取内容
# command1 < file
# 0<1.txt cat # 重定向输入流
# 输出重定向
# 输出重定向也是将本来需要输出标准输出文件stdout中转化为我们的指定文件中
# cat 1.txt > 2.txt # 将1.txt的内容覆盖到2.txt
# cat 1.txt 1> 2.txt # 将1.txt的内容覆盖到2.txt
# cat 1.txt >> 2.txt # 将1.txt的内容追加到2.txt
# cat 1.txt 1>> 2.txt # 将1.txt的内容追加到2.txt
# 标准错误文件重定向
# 借助标准错误文件的文件描述符来重定向stderr
# command 2>file
# 将stdout标准输出文件和stderr标准错误文件合并重定向到一个指定文件中
# command > file 2>&1
# /dev/null 文件
# 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null中,
# /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;
# 如果尝试从该文件读取内容,那么什么也读不到。
# 但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
# command > /dev/null
[本章完...]
网友评论