shell基础学习笔记
2022-06-17 10:54:34 1 举报
AI智能生成
shell基础学习笔记
作者其他创作
大纲/内容
概述
类型
类型种类
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh) 等
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh) 等
类型格式
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell
如: #!/bin/sh
#!/bin/bash
如: #!/bin/sh
#!/bin/bash
运行 Shell 脚本方法
直接运行,脚本中首行需写解释器信息
./test.sh(注意文件的执行权限)
直接运行解释器,其参数就是 shell 脚本的文件名
这种方式脚本中不需要在第一行指定解释器信息,写了也没用
这种方式脚本中不需要在第一行指定解释器信息,写了也没用
/bin/sh test.sh
注释
会被解释器忽略的语句
单行注释
以#号开头
多行注释
每行加#号
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
注释内容...
注释内容...
注释内容...
EOF
:<<'
注释内容...
注释内容...
注释内容...
'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!
注释内容...
注释内容...
注释内容...
!
shell变量
命名规则
首字母不能以数字开头的英文字母,数字和下划线
中间不能有空格,可以使用下划线 _
不能使用标点符号
不能使用bash里的关键字(可用help命令查看保留关键字)
变量类型
局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
shell变量
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
变量赋值
直接赋值
注意:变量名和等号中间不能有空格
注意:变量名和等号中间不能有空格
如 a="yohu!"
语句赋值、
如:将 /etc 下目录的文件名循环出来。
for file in `ls /etc`
或
for file in $(ls /etc)
或
for file in $(ls /etc)
使用变量
使用一个定义过的变量,需要在变量名前面加美元符号
花括号加不加都行
花括号加不加都行
如
a="yohu!"
echo $a
echo ${a}
a="yohu!"
echo $a
echo ${a}
只读变量
使用 readonly 命令可以将变量定义为只读变量
如:
a="qwer"
readonly a
a="qw"
a="qwer"
readonly a
a="qw"
运行结果
script.sh: line 9: a: readonly variable
Exited with error status 1
script.sh: line 9: a: readonly variable
Exited with error status 1
删除变量
使用 unset 命令可以删除变量
如:
a="qw"
unset a
echo ${a}
结果无输出
a="qw"
unset a
echo ${a}
结果无输出
数据类型
字符串
概述
字符串可以用单引号,也可以用双引号,也可以不用引号
索引
第一个字符的索引值为0
单引号
如
a='qwer qwer'
a='qwer qwer'
单引号字符串的限制
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号
如
a="qw"
str="***\"${a}\"***"
echo ${str}
结果
***"qw"***
a="qw"
str="***\"${a}\"***"
echo ${str}
结果
***"qw"***
优点
双引号里可以有变量
双引号里可以出现转义字符
拼接字符串
单引号拼接
如:
a='qwer'
b='asdf'${a}''
echo ${b}
结果:
asdfqwer
a='qwer'
b='asdf'${a}''
echo ${b}
结果:
asdfqwer
双引号拼接
如:
a="qwer"
b="asdf"${a}""
echo ${b}
结果
asdfqwer
a="qwer"
b="asdf"${a}""
echo ${b}
结果
asdfqwer
获取字符串长度
在${#变量名}中
如
a='qwer'
b='asdf'${a}''
echo ${#b}
a='qwer'
b='asdf'${a}''
echo ${#b}
结果输出
8
8
提取字符串
${变量名:索引位置:提取字符数}
如:
c="qwertyuiop"
echo ${c:1:4}
c="qwertyuiop"
echo ${c:1:4}
结果输出:
wert
wert
查找字符的位置
`expr index 字符串 所查字符`
如:
c="qwertyuiop"
echo `expr index ${c} y`
c="qwertyuiop"
echo `expr index ${c} y`
结果输出:
6
6
数组
概述
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0
元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0
定义
用括号来表示数组,数组元素用"空格"符号分割开
数组名=(值1 值2 ... 值n)
单独定义数组的各个分量
可以不使用连续的下标且
下标的范围没有限制,如c
单独定义数组的各个分量
可以不使用连续的下标且
下标的范围没有限制,如c
a=(1 2 3)
b=(1
2
3
4)
2
3
4)
c[0]=0
c[1]=5
c[2]=3
c[1]=5
c[2]=3
读取数组
格式
${数组名[下标]}
echo ${a[2]}
使用 @ 符号可以获取数组中的所有元素
echo ${a[@]}
echo ${a[@]}
获取数组的长度
获取数组元素的个数
l1=${#b[@]}
l=${#b[*]}
获取数组单个元素的长度
ln=${#b[n]}
参数传递
概述
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
实例
将参数传递给文件
1、编辑shell文件1.sh
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
2、赋予可执行权限
chmod +x 1.sh
3、执行
./1.sh 1 2 3
结果
Shell 传递参数实例!
执行的文件名:./1.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
执行的文件名:./1.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
其他参数处理
参数处理说明
$#
传递到脚本的参数个数
$*
以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$
脚本运行的当前进程ID号
$!
后台运行的最后一个进程的ID号
$@
与$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$-
显示Shell使用的当前选项,与set命令功能相同。
$?
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误
$* 与 $@ 区别
相同点
都是引用所有参数。
不同点
只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
实例
shell内容
#!/bin/bash
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
执行脚本
./1.sh 1 2 3
结果输出
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3
1 2 3
-- $@ 演示 ---
1
2
3
实例
shell内容
#!/bin/bash
echo "Shell 传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";
echo "Shell 传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";
执行
./1.sh 1 2 3
结果
Shell 传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3
基本运算符
概述
原生bash不支持简单的数学运算,
但是可以通过其他命令来实现,
如 awk 和 expr,expr 最常用
但是可以通过其他命令来实现,
如 awk 和 expr,expr 最常用
expr 是一款表达式计算工具,
使用它能完成表达式的求值操作
使用它能完成表达式的求值操作
如,两个数相加
val=`expr 2 + 2`
echo "两数之和为 : $val"
运行结果:
两数之和为 : 4
echo "两数之和为 : $val"
运行结果:
两数之和为 : 4
注意
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样
完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
类型
算术运算符
常用算术运算符
+ 加法
- 减法
* 乘法
/ 除法
% 取余
= 赋值
== 等于(用于比较两个数字,相同则返回true)
!= 不等于(用于比较两个数字,不相同则返回true)
注意及实例
乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
例如
#!/bin/bash
a=3
b=7
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
#!/bin/bash
a=3
b=7
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
运行结果
a + b : 10
a - b : -4
a * b : 21
b / a : 2
b % a : 1
a 不等于 b
a + b : 10
a - b : -4
a * b : 21
b / a : 2
b % a : 1
a 不等于 b
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
常用关系运算符
-ep 检测两个数是否相等,相等返回true
-ne 两个数是否不相等,不相等返回true
-gt 左边的数是否大于右边的,是返回true
-lt 左边的数是否小于右边的,是返回true
-ge 左边的数是否大于等于右边的数,是返回true
-le 左边的数是有小于等于右边的数,是返回true
实例
#!/bin/bash
a=3
b=7
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
a=3
b=7
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
运行结果:
3 -eq 7: a 不等于 b
3 -ne 7: a 不等于 b
3 -gt 7: a 不大于 b
3 -lt 7: a 小于 b
3 -ge 7: a 小于 b
3 -le 7: a 小于或等于 b
3 -eq 7: a 不等于 b
3 -ne 7: a 不等于 b
3 -gt 7: a 不大于 b
3 -lt 7: a 小于 b
3 -ge 7: a 小于 b
3 -le 7: a 小于或等于 b
布尔运算符
! 非运算,表达式为 true 则返回 false,否则返回 true。
-o 或运算,有一个表达式为 true 则返回 true。
-a 与运算,两个表达式都为 true 才返回 true。
实例
#!/bin/bash
a=3
b=7
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
a=3
b=7
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
运行结果:
3 != 7 : a 不等于 b
3 小于 100 且 7 大于 15 : 返回 false
3 小于 100 或 7 大于 100 : 返回 true
3 小于 5 或 7 大于 100 : 返回 true
3 != 7 : a 不等于 b
3 小于 100 且 7 大于 15 : 返回 false
3 小于 100 或 7 大于 100 : 返回 true
3 小于 5 或 7 大于 100 : 返回 true
逻辑运算符
&& 逻辑的 AND
|| 逻辑的 OR
实例
#!/bin/bash
a=3
b=7
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
a=3
b=7
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
运行结果:
返回 false
返回 true
返回 false
返回 true
字符串运算符
常用运算符
= 两个字符串是否相等,相等返回 true。
!= 两个字符串是否不相等,不相等返回 true。
-z 检测字符串长度是否为0,为0返回 true。
-n 检测字符串长度是否不为 0,不为 0 返回 true。
$ 检测字符串是否为空,不为空返回 true。
实例
#!/bin/bash
a=3
b=7
a="abcdefg"
b="hijklmn"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
a=3
b=7
a="abcdefg"
b="hijklmn"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
运行结果:
abcdefg = hijklmn: a 不等于 b
abcdefg != hijklmn : a 不等于 b
-z abcdefg : 字符串长度不为 0
-n abcdefg : 字符串长度不为 0
abcdefg : 字符串不为空
abcdefg = hijklmn: a 不等于 b
abcdefg != hijklmn : a 不等于 b
-z abcdefg : 字符串长度不为 0
-n abcdefg : 字符串长度不为 0
abcdefg : 字符串不为空
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性
常用操作符
-b file 检测文件是否是块设备文件,如果是,则返回 true。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。
-d file 检测文件是否是目录,如果是,则返回 true。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file 检测文件是否是有名管道,如果是,则返回 true。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。
-r file 检测文件是否可读,如果是,则返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。
其他检测符
-S: 判断某文件是否 socket。
-L: 检测文件是否存在并且是一个符号链接。
实例
#!/bin/bash
file="/home/tmp/test/1.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
#!/bin/bash
file="/home/tmp/test/1.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
file="/home/tmp/test/1.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
#!/bin/bash
file="/home/tmp/test/1.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
运行结果:
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在
echo命令
用于字符串输出
命令格式
echo string
echo string
显示普通字符串
echo "abcdefg"
echo abcdefg
echo abcdefg
abcdefg
abcdefg
abcdefg
转义字符
echo "\"abcdefg\""
echo \"abcdefg\"
echo \"abcdefg\"
"abcdefg"
"abcdefg"
"abcdefg"
显示变量
read命令
read 命令从标准输入中读取一行
并把输入行的每个字段的值指定给 shell 变量
并把输入行的每个字段的值指定给 shell 变量
实例
#!/bin/bash
echo "输入名字"
read name
echo "$name It is a test"
echo "输入名字"
read name
echo "$name It is a test"
执行结果:
输入名字
eee
eee It is a test
输入名字
eee
eee It is a test
显示换行
-e 开始转义
#!/bin/bash
echo -e "abcdefg\n"
echo "hoho"
#!/bin/bash
echo -e "abcdefg\n"
echo "hoho"
运行结果
abcdefg
hoho
abcdefg
hoho
显示不换行
-c 不换行
#!/bin/bash
echo -e "abcdefg\c"
echo "hoho"
#!/bin/bash
echo -e "abcdefg\c"
echo "hoho"
运行结果
abcdefghoho
abcdefghoho
结果定向至文件
echo "QWERTY" > 1.txt
输出原字符串用单引号
#!/bin/bash
a="sfe"
echo '$a\"'
a="sfe"
echo '$a\"'
运行结果
$a\"
$a\"
显示命令执行结果
使用单引号``
#!/bin/bash
echo `date`
#!/bin/bash
echo `date`
运行结果
Tue 15 Feb 2022 02:55:06 AM UTC
Tue 15 Feb 2022 02:55:06 AM UTC
printf命令
语法
printf 格式控制字符串 [参数]
实例
实例
#!/bin/bash
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 赵 男 70.3475
printf "%-10s %-8s %-4.2f\n" 钱 女 40.6323
printf "%-10s %-8s %-4.2f\n" 孙 女 45.0043
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 赵 男 70.3475
printf "%-10s %-8s %-4.2f\n" 钱 女 40.6323
printf "%-10s %-8s %-4.2f\n" 孙 女 45.0043
执行结果
姓名 性别 体重kg
赵 男 70.35
钱 女 40.63
孙 女 45.00
姓名 性别 体重kg
赵 男 70.35
钱 女 40.63
孙 女 45.00
解析
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中 .2 指保留2位小数。
%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中 .2 指保留2位小数。
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
转义序列
常用
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\\ 一个字面上的反斜杠字符
\ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符
实例
#!/bin/bash
$ printf "a string, no processing:<%s>\n" "A\nB"
$ printf "a string, no processing:<%b>\n" "A\nB"
$ printf "www.runoob.com \a"
$ printf "a string, no processing:<%s>\n" "A\nB"
$ printf "a string, no processing:<%b>\n" "A\nB"
$ printf "www.runoob.com \a"
运行结果:
script.sh: line 2: $: command not found
script.sh: line 3: $: command not found
script.sh: line 4: $: command not found
script.sh: line 2: $: command not found
script.sh: line 3: $: command not found
script.sh: line 4: $: command not found
test命令
概述
用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
常用参数
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
实例
#!/bin/bash
num1=37
num2=75
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
num1=37
num2=75
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
运行结果:
两个数不相等!
两个数不相等!
字符串测试
参数说明
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真
实例
子主题
#!/bin/bash
num1="gaegaa"
num2="dddsss"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
运行结果
两个字符串不相等!
两个字符串不相等!
文件测试
参数说明
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真
实例
#!/bin/bash
if test -e ./1.sh
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
if test -r ./1.sh
then
echo '文件存在且可读!'
else
echo '文件不存在或不可读!'
fi
if test -w ./1.sh
then
echo '文件存在且可写!'
else
echo '文件不存在或不可写!'
fi
if test -x ./1.sh
then
echo '文件存在且可执行!'
else
echo '文件不存在或不可执行!'
fi
if test -s ./1.sh
then
echo '文件存在且至少有一个字符!'
else
echo '文件不存在或没有字符!'
fi
if test -d ./1.sh
then
echo '文件存在且为目录!'
else
echo '文件不存在或不为目录!'
fi
if test -f ./1.sh
then
echo '文件存在且为普通文件!'
else
echo '文件不存在或非普通文件!'
fi
if test -c ./1.sh
then
echo '文件存在且为字符型特殊文件!'
else
echo '文件不存在或不为字符型特殊文件!'
fi
if test -b ./1.sh
then
echo '文件存在且为块特殊文件!'
else
echo '文件不存在或不为块特殊文件!'
fi
if test -e ./1.sh
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
if test -r ./1.sh
then
echo '文件存在且可读!'
else
echo '文件不存在或不可读!'
fi
if test -w ./1.sh
then
echo '文件存在且可写!'
else
echo '文件不存在或不可写!'
fi
if test -x ./1.sh
then
echo '文件存在且可执行!'
else
echo '文件不存在或不可执行!'
fi
if test -s ./1.sh
then
echo '文件存在且至少有一个字符!'
else
echo '文件不存在或没有字符!'
fi
if test -d ./1.sh
then
echo '文件存在且为目录!'
else
echo '文件不存在或不为目录!'
fi
if test -f ./1.sh
then
echo '文件存在且为普通文件!'
else
echo '文件不存在或非普通文件!'
fi
if test -c ./1.sh
then
echo '文件存在且为字符型特殊文件!'
else
echo '文件不存在或不为字符型特殊文件!'
fi
if test -b ./1.sh
then
echo '文件存在且为块特殊文件!'
else
echo '文件不存在或不为块特殊文件!'
fi
执行结果:
文件已存在!
文件存在且可读!
文件存在且可写!
文件存在且可执行!
文件存在且至少有一个字符!
文件不存在或不为目录!
文件存在且为普通文件!
文件不存在或不为字符型特殊文件!
文件不存在或不为块特殊文件!
文件已存在!
文件存在且可读!
文件存在且可写!
文件存在且可执行!
文件存在且至少有一个字符!
文件不存在或不为目录!
文件存在且为普通文件!
文件不存在或不为字符型特殊文件!
文件不存在或不为块特殊文件!
流程控制
if else
sh 的流程控制不可为空,如果 else 分支没有语句执行,就不要写这个 else
fi
语法格式
if condition
then
command1
command2
...
commandN
fi
then
command1
command2
...
commandN
fi
写成一行,适用于终端命令提示符
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
if else
语法格式
if condition
then
command1
command2
...
commandN
else
command
fi
then
command1
command2
...
commandN
else
command
fi
实例
#!/bin/bash
num1=$[7*3]
num2=$[7+5]
if test $[num1] -eq $[num2]
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi
num1=$[7*3]
num2=$[7+5]
if test $[num1] -eq $[num2]
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi
运行结果:
两个数字不相等!
两个数字不相等!
if else-if else
语法格式
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
then
command1
elif condition2
then
command2
else
commandN
fi
实例
#!/bin/bash
a=37
b=75
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
a=37
b=75
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
运行结果:
a 小于 b
a 小于 b
for循环
语法格式
一般格式
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
do
command1
command2
...
commandN
done
实例
#!/bin/bash
for aa in d d2 3d 4e 5e 6u 7b
do
echo "The value is: $aa"
done
for aa in d d2 3d 4e 5e 6u 7b
do
echo "The value is: $aa"
done
运行结果:
The value is: d
The value is: d2
The value is: 3d
The value is: 4e
The value is: 5e
The value is: 6u
The value is: 7b
The value is: d
The value is: d2
The value is: 3d
The value is: 4e
The value is: 5e
The value is: 6u
The value is: 7b
一行
for var in item1 item2 ... itemN; do command1; command2… ;done;
实例
for aa in d d2 3d 4e 5e 6u; do echo "The value is: $aa" ;done;
运行结果:
The value is: d
The value is: d2
The value is: 3d
The value is: 4e
The value is: 5e
The value is: 6u
The value is: d
The value is: d2
The value is: 3d
The value is: 4e
The value is: 5e
The value is: 6u
while循环
语法格式
while condition
do
command
done
do
command
done
实例
输出1-5
输出1-5
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
运行结果:
1
2
3
4
5
1
2
3
4
5
命令说明
let
let
用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来
语法格式
let arg [arg ...]
arg:要执行的表达式
arg:要执行的表达式
自加操作:let no++
自减操作:let no--
简写形式 let no+=10,let no-=20,分别等同于 let no=no+10,let no=no-20。
自减操作:let no--
简写形式 let no+=10,let no-=20,分别等同于 let no=no+10,let no=no-20。
实例
#!/bin/bash
let a=7+3
let b=7-5
echo $a $b
let a=7+3
let b=7-5
echo $a $b
运行结果
10 2
10 2
读取键盘信息 ,示例将输入信息设置为变量FILM,CTRL-D结束循环
#!/bin/bash
echo '按下 <CTRL-D> 退出'
echo -n '请输入: '
while read FILM
do
echo "您输入的是:$FILM !"
done
echo '按下 <CTRL-D> 退出'
echo -n '请输入: '
while read FILM
do
echo "您输入的是:$FILM !"
done
执行效果:按下 <CTRL-D> 退出
请输入: qq
您输入的是:qq !
11
您输入的是:11 !
qwer1234
您输入的是:qwer1234 !
请输入: qq
您输入的是:qq !
11
您输入的是:11 !
qwer1234
您输入的是:qwer1234 !
无限循环
语法格式
while :
do
command
done
do
command
done
while true
do
command
done
do
command
done
for (( ; ; ))
until循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反
until 循环与 while 循环在处理方式上刚好相反
语法格式
until condition
do
command
done
do
command
done
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
实例
输出 0 ~ 9 的数字
输出 0 ~ 9 的数字
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
运行结果
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
case ... esac
case ... esac 为多选择语句每个 case 分支用右圆括号开始,
用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,
esac(就是 case 反过来)作为结束标记。
用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,
esac(就是 case 反过来)作为结束标记。
语法格式
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
实例
#!/bin/bash
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
执行效果:
输入 1 到 4 之间的数字:
你输入的数字为:
5
你没有输入 1 到 4 之间的数字
输入 1 到 4 之间的数字:
你输入的数字为:
1
你选择了 1
输入 1 到 4 之间的数字:
你输入的数字为:
5
你没有输入 1 到 4 之间的数字
输入 1 到 4 之间的数字:
你输入的数字为:
1
你选择了 1
跳出循环
break
break命令允许跳出所有循环
实例
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
执行效果
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:2
你输入的数字为 2!
输入 1 到 5 之间的数字:4
你输入的数字为 4!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:2
你输入的数字为 2!
输入 1 到 5 之间的数字:4
你输入的数字为 4!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束
continue
跳出当前循环
实例
该循环中,echo "游戏结束"永远不会被执行
该循环中,echo "游戏结束"永远不会被执行
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
函数
定义说明
定义格式
[ function ] funname [()]
{
action;
[return int;]
}
{
action;
[return int;]
}
说明
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
实例
#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
执行结果
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
函数调用
调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数
实例
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
执行结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
输入/输出重定向
重定向命令
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file
n > file 将文件描述符为 n 的文件重定向到 file
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file
n >& m 将输出文件 m 和 n 合并
n <& m 将输入文件 m 和 n 合并
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入
文件描述符
0 通常是标准输入(STDIN)
1 是标准输出(STDOUT)
2 是标准错误输出(STDERR)
输出重定向
语法
command1 > file1
语法说明
执行command1然后将输出的内容存入file1
实例
echo "def" >aa
echo "def" >>aa
echo "def" >>aa
def
def
def
输入重定向
语法
command1 < file1
语法说明
以从文件获取输入
实例
wc -l < aa
2
标准错误文件(stderr)
将 stdout 和 stderr 合并后重定向到 file
command > file 2>&1
command >> file 2>&1
对 stdin 和 stdout 都重定向
command 命令将 stdin 重定向到 file1,
将 stdout 重定向到 file2
command 命令将 stdin 重定向到 file1,
将 stdout 重定向到 file2
command < file1 >file2
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
基本形式
command << delimiter
document
delimiter
document
delimiter
作用
将两个 delimiter 之间的内容(document) 作为输入传递给 command
注意事项
结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
开始的delimiter前后的空格会被忽略掉
实例
#!/bin/bash
wc -l << EOF
aaa
bbb
cccccccccccc
EOF
wc -l << EOF
aaa
bbb
cccccccccccc
EOF
运行结果:
3
3
#!/bin/bash
cat << EOF
aaa
bbb
cccccccccccc
EOF
cat << EOF
aaa
bbb
cccccccccccc
EOF
aaa
bbb
cccccccccccc
bbb
cccccccccccc
/dev/null 文件
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃
语法
command > /dev/null
屏蔽 stdout 和 stderr
command > /dev/null 2>&1
注意
0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)
2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出
实例
* */2 * * * /usr/sbin/logrotate /etc/logrotate.d/tomcat >/dev/null 2>&1
文件包含
和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件
格式
. filename # 注意点号(.)和文件名中间有一空格
source filename
实例
7.sh 内容
#!/bin/bash
cat << EOF
aaa
bbb
cccccccccccc
EOF
8.sh 内容
#!/bin/bash
. ./7.sh
执行8.sh
#!/bin/bash
cat << EOF
aaa
bbb
cccccccccccc
EOF
8.sh 内容
#!/bin/bash
. ./7.sh
执行8.sh
执行结果
aaa
bbb
cccccccccccc
aaa
bbb
cccccccccccc
注意,7.sh不需要可执行权限
0 条评论
下一页