Linux下命令行程序叫做 Shell,除解释用户的输入命令,还可以:
调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果;
在多个程序之间传递数据,把一个程序的输出作为另一个程序的输入;
Shell 本身也可以被其他程序调用。
Shell是一种脚本语言(常见的解释器有bash、sh、csh等),支持基本的编程元素,如:
if...else 选择结构,case 开关语句,for、while、until 循环;
变量、数组、字符串、注释、加减乘除、逻辑运算等概念;
函数,包括用户自定义的函数和内置函数(例如 printf、export、eval 等)。
Shell脚本也可以包含外部脚本(其他脚本文件),将外部脚本的内容合并到当前脚本。
. filename
#或
source filename
两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。
被包含脚本不需要有执行权限。
printf函数
除用echo输出外,printf有更强的控制方式:
与c中的printf类似,但是参数不用括号,参数间用空格风格
参数比控制字符多时,也会按顺序输出;
参数比控制字符少时,%s用NULL代替,%d用0代替;
如:
printf '%s %d' a #输出:a
printf 'Test: %s %s' a b c d e#输出:
Test: a b
Test: c d
Test: e
变量基础
创建shell脚本时,必须在文件第一行指定要使用的shell:
#!/bin/bash
set -e# 遇到执行错误,退出(默认继续执行下一条)
set -u# (set -o nounset),使用未初始话变量时,脚本自动退出
脚本创建完成后,就需要执行脚本:
chmod u+x添加X权限,调用文件执行;如./file.sh
通过过sh file.sh来执行:不需要添加执行权限;
root用户可通过点号(.)来执行(不需执行权限),如:
. /lib/init/vars.sh
变量:
直接赋值即定义:count=100 #等号两边不能有空格
通过$来引用变量:$count或$
readonly修饰只读变量:readonly count=100
unset删除变量:unset count
如:
count=1
count=`expr $count+1`
特殊变量:
通过特殊变量可获取shell的参数:
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。但是当它们被双引号(" ")包含时:
"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;
"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
shift:移动变量,将每个参数变量减一;如$3变为$2;
if [ -n "$1" ]:来判断参数是否已传递。
更多的参数,需要加花括号引用:$;
获取最后一个参数:${!#}。
变量替换:根据变量的状态(是否为空、是否定义等)来改变它的值
三种类型变量:
局部变量:在脚本或命令中定义,仅在当前shell实例中有效。
环境变量:所有的程序,包括shell启动的程序,都能访问环境变量。shell脚本也可以定义环境变量。
shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
字符串类型
字符串可用单双引号:
单引号的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
字符串连接:
直接联接两个字符串
newfile=$"new"
newfile=$$
使用printf(使用反引号)可以进行更复杂的联接
newstr=`printf "%s%s" "$STR" "$USER"`
字符串操作
$:删除VALUE字符串中以分隔符“.”匹配的右边字符,保留左边字符。
$:删除VALUE字符串中以分隔符“.”匹配的左边字符,保留右边字符。
补充:
“*”表示通配符,用于匹配字符串将被删除的字串。
“.”表示字符串中分隔符,可以为任意一个或多个字符。
“%”表示从左向右匹配,“#”表示从右向左匹配,“/”表示替换,都属于非贪婪匹配,即匹配符合通配符的最短结果。而“%%”、“##”和“//”,都属于贪婪匹配,即匹配符合通配符的最长结果。
数组类型
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组)。初始化时不需要定义数组大小,数组元素的下标由0开始。数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name=(value1 ... valueN)
定义:
myAry=(A B "CD" 1 2)
也可以使用下标来定义数组:
myAry[0]=value0
myAry[1]=value1
...
myAry[N]=valueN
读取:
$
echo $ 输出第一个元素
使用@ 或 * 可以获取数组中的所有元素
echo "数组的元素为: $"
echo "数组的元素为: $"
长度:
获取数组长度的方法与获取字符串长度的方法相同
echo "数组长度: ${#myAry[*]}"
echo "数组元素个数: ${#myAry[@]}"
删除操作
清除某个元素:unset myAry[1],这里清除下标为1的数组;
清空整个数组:unset myAry;
切片访问
$
中间以":"隔开,
起始位置省略从0开始;
长度省略,就取后面所有的项;
切片后返回的是字符串,可以通过 新数组=($)来获取
起始位置可以为负数,但必须以放在()中,长度不能为负数
$ #获取前四个元素
$ #获取后两个元素
newAry=$ #生成新的切片
模式替换
$
例如:$
数组遍历
数组遍历我们使用for语句来演示:
for v in $; do
echo $v;
done
运算符说明
算术运算符:原生bash不支持简单的数学运算,但可以通过其他命令(如 awk 和 expr)来实现 :
+、-、*、/、%
=、==、!=
expr是一款表达式计算工具,使用它可以完成表达式的求值操作:
在 expr中的表达式与运算符之间要有空格,否则错误;
在[ $a == $b ]与[ $a != $b ]中,要需要在方括号与变量以及变量与运算符之间也需要有空格, 否则错误。
如:
echo `expr $a + $b`
echo `expr $a\*$b` #乘号要转义
val=`expr 10 - 3` #表达式需要用反引号(`,~键那个)括起来
关系运算符:只支持数字(或值为数字的字符串)
-eq:两个数是否相等,相等返回 true。
-ne:两个数是否相等,不相等返回 true。
-gt:左边的数是否大于右边的。
-lt:左边的数是否小于右边的。
-ge:左边的数是否大等于右边的。
-le:左边的数是否小于等于右边的。
如:
[ 5 -eq 3 ] 返回 false
[ 5 -ne 3 ] 返回 true #方括号与变量以及变量与运算符之间也需要有空格
布尔运算符
!:非, [ !false ]为true
-o:或
-a:与, [ $a -a $b ],都为true是为true
字符串运算符
=:两个字符串是否相等,相等返回 true。
!=:两个字符串是否相等,不相等返回 true。
-z:字符串长度是否为0,为0返回 true。
-n:字符串长度是否为0,不为0返回 true。
[ str ]:字符串是否为空,不为空返回 true。
如,以a="test"为例
[ -z $a ] 返回 false
[ $a ] 返回 true
文件测试运算符:检测文件的各种属性
-b file:文件是否是块设备文件,如果是,则返回 true。
-c file:文件是否是字符设备文件,如果是,则返回 true。
-d file:文件是否是目录,如果是,则返回 true。
-f file:文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-r file:文件是否可读,如果是,则返回 true。
-w file:文件是否可写,如果是,则返回 true。
-x file:文件是否可执行,如果是,则返回 true。
-s file:文件是否为空(文件大小是否大于0),不为空返回 true。
-e file:文件(包括目录)是否存在,如果是,则返回 true。
-g file:文件是否设置了 SGID 位,如果是,则返回 true
-k file:文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file:文件是否是具名管道,如果是,则返回 true。
-u file:文件是否设置了 SUID 位,如果是,则返回 true。
如:
[ -r $file ] #是否可读
[ -e $file ] #是否存在
条件语句
shell语句默认使用回车分隔(每条语句一行),若要在一行中输入多条语句可通过分号分隔实现:
if [ *** ]; then
while [ *** ]; do
针对数字与字符串判断有扩展特性,放在判断条件时与if/while等间要保证有空格:
双括号(( expression )):用于数学表达式,内部可是任意的数学计算或比较表达式
if (( $var**2 > 90 ))
then
((var2=$var**2))
fi
双方括号[[ expression ]]:expression两边要加空格,用于字符串处理
while [[ "$a" > "$b" ]]
方括号[ expr ]:逻辑判断(见运算符说明部分)
if [ -d file ]条件检测
if语句
if
then
Command
else
Command
fi
case语句
case 值 in
模式1)
command...
;;
模式2)
command...
;;
*)
command...
;;
esac
取值后面必须为关键字 in,每一模式必须以右括号结束。
取值可以为变量或常数;匹配某一模式后,执行其后所有命令直至 ;;(双分号)。
如果无一模式匹配,执行*后的命令。
如:
for a in root xugd test none; do
echo $a
case $a in
root)
echo admin
;;
xugd | test ) #多个值可用|分隔
echo normal
;;
# *)
# echo default
# ;;
esac
done
for循环
for循环有两种常用用法,for...in与for((赋值;条件;运算语句))
for var in list # for((赋值;条件;运算语句))
do
commands
done
示例:循环十次
for((i=1;i
echo $(expr $i \* 3 + 1);
done
for i in $(seq 1 10)
do
echo $(expr $i \* 3 + 1);
done
#for i in ;do
for i in 1 2 3 4 5;do #直接把值列出即可(用空格分隔)
echo $(expr $i \* 3 + 1);
done
示例:枚举文件
for file in /proc/*; do
echo $file
done
for file in $(ls *.sh); do
echo $file
done
while循环
while
do
action
done;
例:
i=10;
while [[ $i -gt 5 ]]; do
echo $i;
((i--));
done;
until循环
until
do
action
done
例:
a=10;
until [[ $a -lt 0 ]];do
echo $a;
((a—));
done;
# break 命令不执行当前循环体内break下面的语句从当前循环退出。
# continue 命令是程序在本循体内忽略下面的语句,从循环头开始执行。
shell函数
Shell函数必须先定义后使用,function关键字是可选的:
[function] function_name () {
list of commands
[ return value ]
}
注意:
调用函数只需要给出函数名,不需要加括号;
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值;
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败;
函数的参数可以通过 $n 得到;
像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项。
Echo输出控制
通过echo可方便输出,并控制颜色格式:
-e 用来开启echo中的转义
设置颜色的格式:
echo -e "\033[字背景颜色;文字颜色m字符串"
echo -e "\e[0m":恢复默认
输出红色字体 abc,背景色不变;然后还原
echo -e '\033[0;31;1m abc \033[0m'
注:
文字颜色后面有个m
字符串前后可以没有空格,如果有的话,输出也是同样有空格
字颜色:30—–37
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m”
字背景颜色范围:40—–47
echo -e “\033[40;37m 黑底白字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
echo -e “\033[42;37m 绿底白字 \033[0m”
echo -e “\033[43;37m 黄底白字 \033[0m”
echo -e “\033[44;37m 蓝底白字 \033[0m”
echo -e “\033[45;37m 紫底白字 \033[0m”
echo -e “\033[46;37m 天蓝底白字 \033[0m”
echo -e “\033[47;30m 白底黑字 \033[0m”
控制选项说明
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m — \33[37m 设置前景色
\33[40m — \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标
领取专属 10元无门槛券
私享最新 技术干货