Android源码的编译环节涉及很多Shell脚本,以及在Android.mk中也大量使用了Shell命令。为了能够看懂Shell脚本,把Shell相关的基础知识点敲了一遍并写成了这篇文档,加深记忆的同时对知识点的掌握很有帮助。
shell
shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。shell 既是一种命令语言,又是一种程序设计语言。
shell 脚本
shell 脚本就是用 shell 编写的脚本程序。平时说的 shell 通常指的是 shell 脚本。但其实两者是两个不同的概念。
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 。但Bourne Shell和Bourne Again Shell区别不大.
shell 环境
在文本编辑器的第一行用 #! 告诉系统其后路径所指定的程序即是解释此脚本文件的 shell 程序。
第一个shell脚本
创建一个名为shell_test的文本文件,书写以下内容。
#!/bin/bash
echo "HelloWorld!"
然后保存,并给予脚本执行权限
$chmod +x shell_test
$./shell_test
HelloWorld!
"#!" 用来告诉系统脚本由什么解释器执行。echo 用来输出内容到窗口。
./ 意味着是去当前目录下执行可执行文件。
变量
定义
Test="Test!"
注意: 变量名和等号之间不能有空格.
语句中定义
for file in `ls /etc`
或
for file in $(ls /etc)
以上语句将 /etc 下目录的文件名循环出来.
使用变量
$ 符号
在变量前面添加 $ 符号,就可以使用变量.
#!/bin/bash
my_name="fukaiqiang"
echo $my_name
$./shell_test.sh
fukaiqiang
{} 花括号
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,例如:
#!/bin/bash
for i in abc def ghi;do
echo "${i}xxx"
done
for i in abc def ghi;do
echo "$ixxx"
done
$./shell_test.sh
abcxxx
defxxx
ghixxx
如果不给变量 i 添加 {} ,解释器就会把$ixxx当成一个变量(其值为空),结果如上.可以看出加 {} 和 不加的差异. 推荐添加 {} ,是一个好的编程习惯.
变量的重新定义
#!/bin/bash
my_name="fukaiqiang"
echo $my_name
my_name="jack ma"
echo ${my_name}
$./shell_test.sh
fukaiqiang
jack ma
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变.如果尝试更改只读变量,结果报错:
#!/bin/bash
my_name="fukaiqiang"
echo $my_name
readonly my_name
my_name="jack ma"
echo ${my_name}
$./shell_test.sh
fukaiqiang
./shell_test.sh: 行 5: my_name: 只读变量
fukaiqiang
删除变量
#!/bin/bash
my_name="fukaiqiang"
unset my_name
echo ${my_name}
变量被删除后不能再次使用.以上实例执行将没有任何输出.
不能删除只读变量:
#!/bin/bash
my_name="fukaiqiang"
readonly my_name
unset my_name
echo ${my_name}
$./shell_test.sh
./shell_test.sh: 第 4 行: unset: my_name: 无法取消设定: 只读 variable
fukaiqiang
变量类型
- 局部变量:在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量。必要的时候shell脚本也可以定义环境变量。
- shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量。
字符串
单引号字符串
#!/bin/bash
echo 'str str str'
$./shell_test
str str str
特点:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的。
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
#!/bin/bash
str="HelloWorld!"
echo '${str}'
$./shell_test
${str}
双引号字符串
#!/bin/bash
str="HelloWorld!"
echo "fkq \"${str}\""
$./shell_test
fkq "HelloWorld!"
特点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串
#!/bin/bash
str="Wolrd"
echo 'Hello,${str}'
echo "Hello,${str}"
$./shell_test
Hello,${str}
Hello,Wolrd
获取字符串长度
#!/bin/bash
str="Wolrd"
echo "${#str}"
$./shell_test
5
截取字符串
#!/bin/bash
str="Wolrd"
echo "${str:0:1}"
echo "${str:0:2}"
echo "${str:0:3}"
echo "${str:0:4}"
echo "${str:1:1}"
echo "${str:1:2}"
echo "${str:1:3}"
echo "${str:1:4}"
$./shell_test
W
Wo
Wol
Wolr
o
ol
olr
olrd
从索引0开始和从索引1开始,从结果来看,有点不对劲,这里不知道你看出来了没有。
查找字符在字符串中的索引
默认返回第一个找到的字符的索引。
#!/bin/bash
str="Wolrd"
echo `expr index ${str} o`
$./shell_test
2
格式:expr index + 字符串 + 字符。注意是用符号包裹,而不是" "
数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小,数组元素的下标由 0 开始编号。
定义数组
array_name=(value1 value2 ... valuen)
fkq_array=("A" "B" "C" "D")
读取数组元素
#!/bin/bash
echo ${fkq_array[0]}
echo ${fkq_array[1]}
echo ${fkq_array[2]}
echo ${fkq_array[3]}
$./shell_test.sh
A
A
B
C
D
设置数组元素(也可以用来定义数组)
#!/bin/bash
fkq_array[0]="E"
fkq_array[1]="F"
fkq_array[2]="G"
fkq_array[3]="H"
echo ${fkq_array[0]}
echo ${fkq_array[1]}
echo ${fkq_array[2]}
echo ${fkq_array[3]}
$./shell_test.sh
E
F
G
H
获取数组中的所有元素
#!/bin/bash
fkq_array[0]="E"
fkq_array[1]="F"
fkq_array[2]="G"
fkq_array[3]="H"
echo ${fkq_array[@]}
echo ${fkq_array[*]}
$./shell_test.sh
E F G H
E F G H
获取数组的长度
#!/bin/bash
fkq_array[0]="E"
fkq_array[1]="F"
fkq_array[2]="G"
fkq_array[3]="H"
echo ${#fkq_array[@]}
echo ${#fkq_array[*]}
$./shell_test.sh
4
4
运算符
算数运算符
- expr
shell进行数学计算的一种方式是借助命令实现,用的比较多的是expr.expr 是一款表达式计算工具,使用它能完成表达式的求值操作.
#!/bin/bash
val=`expr 2 + 1`
echo ${val}
val=`expr 2 - 1`
echo ${val}
val=`expr 2 * 1`
echo ${val}
val=`expr 2 / 1`
echo ${val}
a=20
b=40
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
注意:
- 2 + 1 的 + 号两边都要有空格.
- expr表达式要用反引号 ` 括起来,而不是单引号 '
- 乘号(*)前边必须加反斜杠()才能实现乘法运算
- [ ]
shell进行数学计算的另一种方式是借助方括号:
#!/bin/bash
a=10
b=10
result=$[ a + b ]
echo $result
$./shell_test
20
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字.
以下if表达式后面会讲.
假定变量 a 为 20,变量 b 为 40.
- -eq (可理解为equal的缩写)
检测两个数是否相等,相等返回 true. - -ne(可理解not equal的缩写)
检测两个数是否不相等,不相等返回 true - -gt(可以理解为bigger between的缩写)
检测左边的数是否大于右边的,如果是,则返回 true - -lt(可以理解为smaller between的缩写)
检测左边的数是否小于右边的,如果是,则返回 true - -ge
检测左边的数是否大于等于右边的,如果是,则返回 true - -le
检测左边的数是否小于等于右边的,如果是,则返回 true
#!/bin/bash
a=20
b=40
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} -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}" 的前面 和 "${b}" 的后面要有空格.
布尔运算符
- -o 或运算
或运算,有一个表达式为 true 则返回 true - -a 与运算
与运算,两个表达式都为 true 才返回 true
#!/bin/bash
a=20
b=40
if [ ${a} -le ${b} -o ${a} -ge ${b} ]
then
echo "有一个表达式为 true"
else
echo "有零个表达式为 true"
fi
if [ ${a} -le ${b} -a ${a} -ge ${b} ]
then
echo "两个表达式都为true"
else
echo "两个表达式或者都为flase或者有一个是false"
fi
$./shell_test.sh
有一个表达式为 true
两个表达式或者都为flase或者有一个是false
逻辑运算符
- && 逻辑And 两个表达式都为true
- || 逻辑or 有一个表达式为 true
#!/bin/bash
a=20
b=40
if [[ ${a} -le ${b} || ${a} -ge ${b} ]]
then
echo "有一个表达式为 true"
else
echo "有零个表达式为 true"
fi
if [[ ${a} -le ${b} && ${a} -ge ${b} ]]
then
echo "两个表达式都为true"
else
echo "两个表达式或者都为flase或者有一个是false"
fi
注意: 这里是两个方括号
字符串运算符
- =
检测两个字符串是否相等 - !=
检测两个字符串是否不相等,不相等返回 true - -z
检测字符串长度是否为 0,为 0 返回 true - -n
检测字符串长度是否不为 0,不为 0 返回 true - $
检测字符串是否为空,不为空返回 true
#!/bin/bash
a="abc"
b="def"
if [ ${a} = ${b} ]
then
echo "a = b"
else
echo "a != b"
fi
if [ ${a} != ${b} ]
then
echo "a != b"
else
echo "a = b"
fi
if [ -z ${a} ]
then
echo "a 长度为 0"
else
echo "a 长度不为 0"
fi
if [ -n ${a} ]
then
echo "a 长度不为 0"
else
echo "a 长度为 0"
fi
if [ ${a} ]
then
echo "a 不为空"
else
echo "a 为空"
fi
$./shell_test.sh
a != b
a != b
a 长度不为 0
a 长度不为 0
a 不为空
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
- -r 是否可读
- -w 是否可写
- -x 是否可执行
- -f 是否是普通文件
- -d 是否是目录
- -s 是否文件是非空的
- -e 是否文件存在
#!/bin/bash
a="/media/fukaiqiang/Disk960/startTool.cpp"
if [ -r ${a} ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w ${a} ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -f ${a} ]
then
echo "文件是普通文件"
else
echo "文件不是普通文件"
fi
if [ -d ${a} ]
then
echo "文件是目录"
else
echo "文件不是目录"
fi
if [ -s ${a} ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e ${a} ]
then
echo "文件存在"
else
echo "文件不存在"
fi
$./shell_test.sh
文件可读
文件可写
文件是普通文件
文件不是目录
文件不为空
文件存在
echo 命令
用于输出字符串
输出普通字符串
#!/bin/bash
echo "Hello World!"
echo Hello World
$./shell_test.sh
Hello World!
Hello World
可以带双引号,也可以不带双引号.
打印特殊字符
#!/bin/bash
echo "\"Hello World!\""
echo \"Hello World!\"
$./shell_test.sh
"Hello World!"
"Hello World!"
可以添加双引号,也可以不添加.
显示变量
#!/bin/bash
read name
echo "Hello ${name}!"
read 是从标准输入中读取一行,然后赋值给变量name.
$./shell_test.sh
fkq
Hello fkq!
显示换行
#!/bin/bash
read name
echo -e "Hello ${name}! \n"
echo "Hello Beijing!"
-e 是开启转义.
显示不换行
#!/bin/bash
read name
echo -e "Hello ${name}! \c"
echo "Hello Beijing!"
-e 开启转义 \c 不换行
显示结果定向到某文件
#!/bin/bash
echo "Hello Beijing!" > fkq
$vim fkq
Hello Beijing!
原样输出字符串
用单引号实现这个功能.
#!/bin/bash
name="fukaiqiang"
echo 'Hello ${name}!'
$./shell_test.sh
Hello ${name}!
显示命令执行结果
#!/bin/bash
echo `date`
$./shell_test.sh
Wed Oct 27 21:58:19 CST 2021
注意,这里使用的是反引号
test命令
test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试.
数值测试
- -eq 等于则为真
- -ne 不等于则为真
- -gt 大于则为真
- -ge 大于等于则为真
- -lt 小于则为真
- -le 小于等于则为真
#!/bin/bash
a=10
b=10
if test ${a} -eq ${b}
then
echo 两个数相等
else
echo 两个数不相等
fi
echo a = ${a}
echo b = ${b}
if test $[a] -eq $[b]
then
echo 两个数相等
else
echo 两个数不相等
fi
echo a = $[a]
echo b = $[b]
$./shell_test
两个数相等
a = 10
b = 10
两个数相等
a = 10
b = 10
从以上例子,会发现获取变量的值可以使用[ ],也可以使用{ }。
字符串测试
- = 等于则为真
- != 不相等则为真
- -z 字符串的长度为零则为真
- -n 字符串的长度不为零则为真
#!/bin/bash
a="a"
b="a"
if test ${a} == ${b}
then
echo "两个字符串相等!"
else
echo "两个字符串不相等!"
fi
if test ${a} != ${b}
then
echo "两个字符串不相等!"
else
echo "两个字符串相等!"
fi
if test -z ${a}
then
echo "字符串长度为零!"
else
echo "字符串长度不为零!"
fi
if test -n ${a}
then
echo "字符串长度不为零!"
else
echo "字符串长度为零!"
fi
$./shell_test
两个字符串相等!
两个字符串相等!
字符串长度不为零!
字符串长度不为零!
文件测试
- -e 如果文件存在则为真
- -r 如果文件存在且可读则为真
- -w 如果文件存在且可写则为真
- -x 如果文件存在且可执行则为真
- -s 如果文件存在且至少有一个字符则为真
- -d 如果文件且为目录则为真
- -f 如果文件存在且为普通文件则为真
- -c 如果文件存在且为字符型特殊文件则为真
- -b 如果文件存在且为块特殊文件则为真
#!/bin/bash
if test -e /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件存在!"
else
echo "文件不存在!"
fi
if test -r /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件可读!"
else
echo "文件不可读!"
fi
if test -w /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件可写!"
else
echo "文件不可写!"
fi
if test -x /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件可执行!"
else
echo "文件不可执行!"
fi
if test -s /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件不为空!"
else
echo "文件为空!"
fi
if test -d /home/fukaiqiang/Code/Shell
then
echo "文件为目录!"
else
echo "文件不是目录!"
fi
if test -f /home/fukaiqiang/Code/Shell/shell_test
then
echo "文件存在且为普通文件!"
else
echo "文件不存在或不为普通文件!"
fi
if test -c /dev/null
then
echo "文件存在且为字符型特殊文件!"
else
echo "文件不存在或不为字符型特殊文件!"
fi
if test -b /dev/sda
then
echo "文件存在且为块特殊文件!"
else
echo "文件不存在或不为块特殊文件!"
fi
$./shell_test
文件存在!
文件可读!
文件可写!
文件可执行!
文件不为空!
文件为目录!
文件存在且为普通文件!
文件存在且为字符型特殊文件!
文件存在且为块特殊文件!
连接测试条件
Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低。
#!/bin/bash
cd /bin
if test -e /bin/busybox -o -e /bin/bash
then
echo "dev/null and /dev/mem 至少有一个存在"
else
echo "dev/null and /dev/mem 一个也不存在"
fi
if test -e /bin/busybox -a -e /bin/bash
then
echo "dev/null and /dev/mem 都存在"
else
echo "dev/null and /dev/mem 不是都存在"
fi
if ! test -e /bin/busybox -a -e /bin/bash
then
echo "dev/null and /dev/mem 不是都存在"
else
echo "dev/null and /dev/mem 都存在"
fi
$./shell_test.sh
dev/null and /dev/mem 至少有一个存在
dev/null and /dev/mem 都存在
dev/null and /dev/mem 都存在
流程控制
if else
if fi
#!/bin/bash
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
shell与其他语言不同,如果没有else部分为空内容,就不能添加else部分,推荐书写代码为一行。
if else fi
#!/bin/bash
if [ $(ps -ef | grep -c "ssh") -lt 1 ]
then
echo "true"
else
echo "false"
fi
if elif fi
#!/bin/bash
a=10
b=20
if [ ${a} = ${b} ]
then
echo "a = b"
elif [ ${a} -gt ${b} ]
then
echo "a > b"
else
echo "a < b"
fi
$./shell_test.sh
a < b
for 循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
#!/bin/bash
for num in 1 2 3 4 5
do
echo num: ${num}
done
$./shell_test.sh
num: 1
num: 2
num: 3
num: 4
num: 5
while语句
while condition
do
command
done
#!/bin/bash
num=1
while(($num<=10))
do
echo $num
let "num++"
done
$./shell_test.sh
1
2
3
4
5
6
7
8
9
10
例子中使用了Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。后面会讲解。
while 循环也可以用于读取键盘信息
#!/bin/bash
echo "按下 Ctrl-D 退出"
echo -n "输入你最喜欢的电影名:"
while read FILM
do
echo "是的!$FILM 是一个好电影"
done
$./shell_test.sh
按下 Ctrl-D 退出
输入你最喜欢的电影名:肖生克的救赎
是的!肖生克的救赎 是一个好电影
阿甘正传
是的!阿甘正传 是一个好电影
无限循环
while :
do
command
done
while true
do
command
done
for (( ; ; ))
#!/bin/bash
while :
do
echo "无限循环中"
done
while true
do
echo "无限循环中"
done
for (( ; ; ))
do
echo "无限循环中"
done
until 循环
until 循环执行一系列命令直至条件为 true 时停止,和 while 正好相反。
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环
until condition
do
command
done
#!/bin/bash
a=20
until [ ! ${a} -gt 10 ]
do
echo ${a}
let a--
done
$./shell_test.sh
20
19
18
17
16
15
14
13
12
11
case ... esac
case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。
取值可以为变量或常数。
用 * 表示其他值。
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
#!/bin/bash
a=20
case ${a} in
10)
echo "a = 10"
;;
20)
echo "a = 20"
;;
*)
echo "a != 10 and a != 20"
;;
esac
$./shell_test.sh
a = 20
#!/bin/bash
site="baidu"
case ${site} in
"google")
echo "a = google"
;;
"baidu")
echo "a = baidu"
;;
*)
echo "a != google and a != baidu"
;;
esac
$./shell_test.sh
a = baidu
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
- break
break命令允许跳出所有循环
#!/bin/bash
site="baidu"
echo -n "请输入 1 -5 之间的数字:"
while true
do
read num
case ${num} in
1|2|3|4|5)
echo 输入的数字是 ${num}
;;
*)
echo -n "输入的数字不是 1 - 5 之间,游戏结束"
break
;;
esac
done
$./shell_test.sh
请输入 1 -5 之间的数字:1
输入的数字是 1
5
输入的数字是 5
6
输入的数字不是 1 - 5 之间,游戏结束
- continue
continue命令不会跳出所有循环,仅仅跳出当前循环
#!/bin/bash
site="baidu"
echo -n "请输入 1 -5 之间的数字,退出请按Ctrl+C:"
while true
do
read num
case ${num} in
1|2|3|4|5)
echo 输入的数字是 ${num}
;;
*)
echo "您输入的数字不是 1 - 5 之间,请输入其他数字"
continue
;;
esac
done
$./shell_test.sh
请输入 1 -5 之间的数字,退出请按Ctrl+D:1
输入的数字是 1
2
输入的数字是 2
5
输入的数字是 5
6
您输入的数字不是 1 - 5 之间,请输入其他数字
10
您输入的数字不是 1 - 5 之间,请输入其他数字
1
输入的数字是 1
您输入的数字不是 1 - 5 之间,请输入其他数字
^C
函数
第一个Shell函数
function可以省略,return也可以省略,参数也可以省略。
如果不加return语句,一般会返回值。
调用函数仅使用其函数名即可。
函数返回值在调用该函数后通过 $? 来获得。
[ function ] funname [()]
{
action;
[return int;]
}
无返回值函数
#!/bin/bash
function firstFun(){
echo "这是我的第一个Shell函数"
}
echo "----函数执行开始----"
firstFun
echo "firstFun函数的返回值是 $?"
echo "----函数执行完毕----"
$./shell_test.sh
----函数执行开始----
这是我的第一个Shell函数
firstFun函数的返回值是 0
----函数执行完毕----
有返回值函数
#!/bin/bash
function timesFun(){
echo "这个函数会对两个数字进行乘法运算"
echo "请输入第一个数字"
read num1
echo "请输入第二个数字"
read num2
return $(( ${num1} * ${num2} ))
}
timesFun
echo -n "输入的两个数字的乘法值是 $? "
$./shell_test.sh
这个函数会对两个数字进行乘法运算
请输入第一个数字
2
请输入第二个数字
3
输入的两个数字的乘法值是 6
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 1表示第一个参数,$2表示第二个参数...
注意:当n>=10时,需要使用${n}来获取参数。
#!/bin/bash
function withParameters(){
echo "withParameters函数的返回值是 $1"
echo "withParameters函数的返回值是 $2"
echo "withParameters函数的返回值是 $3"
echo "withParameters函数的返回值是 $4"
echo "withParameters函数的返回值是 $5"
echo "withParameters函数的返回值是 $6"
echo "withParameters函数的返回值是 $7"
echo "withParameters函数的返回值是 $8"
echo "withParameters函数的返回值是 $9"
echo "withParameters函数的返回值是 $10"
echo "withParameters函数的返回值是 ${10}"
echo "withParameters函数的返回值是 ${11}"
echo "withParameters函数的返回值是 ${12}"
echo "withParameters函数的返回值是 ${13}"
echo "withParameters函数的返回值是 ${14}"
echo "withParameters函数的返回值是 ${15}"
echo "withParameters函数个数是 ${#}"
echo "withParameters函数的所有参数是 ${*}"
echo "当前脚本运行的shell进程id是 ${$}"
echo "后台运行的最后一个进程的id是 ${!}"
echo "withParameters函数的所有参数是 ${@}"
echo "显示withParameters函数的当前选项是 ${-}"
echo "显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误: ${?}"
}
withParameters 1 2 3 4 5 6 7 8 9 A B C D E F
$./shell_test.sh
withParameters函数的返回值是 1
withParameters函数的返回值是 2
withParameters函数的返回值是 3
withParameters函数的返回值是 4
withParameters函数的返回值是 5
withParameters函数的返回值是 6
withParameters函数的返回值是 7
withParameters函数的返回值是 8
withParameters函数的返回值是 9
withParameters函数的返回值是 10
withParameters函数的返回值是 A
withParameters函数的返回值是 B
withParameters函数的返回值是 C
withParameters函数的返回值是 D
withParameters函数的返回值是 E
withParameters函数的返回值是 F
withParameters函数个数是 15
withParameters函数的所有参数是 1 2 3 4 5 6 7 8 9 A B C D E F
当前脚本运行的shell进程id是 30052
后台运行的最后一个进程的id是
withParameters函数的所有参数是 1 2 3 4 5 6 7 8 9 A B C D E F
显示withParameters函数的当前选项是 hB
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误: 0
用${#}
获取参数个数,用 ${*}
获取所有的参数,用${$}
获取脚本运行的进程id,用${!}
获取后台最后一个进程id,用${@}
获取函数的所有参数,用$-
显示Shell使用的当前选项,用${?}
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
${$}
、${!}
、$-
从上面例子中理解的还不是很清楚,以后有了更好的示例会补充在这里。
Shell 输入/输出重定向
有以下几个符号,可以实现输入或者输出重定向。这里重点说下符号 ">" 和 "<"。
- command > file 将输出重定向到文件
- command < file 将输入重定向到文件
- command >> file 将输出以追加的方式重定向到 file
- n > file 将文件描述符 n 重定向到文件
- n >> file 将文件描述符 n 以追加的方式重定向到文件
- n >& m 将输出文件m和n合并
- n <& m 将输入文件m和n合并
- << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
这里我们重点说下 输出重定向和输入重定向。
输出重定向
{ fukaiqiang@superman /home/fukaiqiang/tmp }
$who > my_user
{ fukaiqiang@superman /home/fukaiqiang/tmp }
$cat my_user
fukaiqiang tty7 2021-10-29 11:31 (:0)
输入重定向
{ fukaiqiang@superman /home/fukaiqiang/tmp }
$wc -l < my_user
1
既有输出重定向,又有输入重定向
{ fukaiqiang@superman /home/fukaiqiang/tmp }
$wc -l < my_user > my_user_line
{ fukaiqiang@superman /home/fukaiqiang/tmp }
$cat my_user_line
1
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
command << delimiter
document
delimiter
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:
- 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
- 开始的delimiter前后的空格会被忽略掉。
#!/bin/bash
cat << EOF
学会shell
提交技术能力
EOF
$./shell_test.sh
学会shell
提交技术能力
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
$ command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
command > /dev/null 2>&1
注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出,2>&1 表示将标准输出和错误输出一起输出到文件,>
Shell 文件包含
Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。类似与其他语言的include。
这里定义一个shell1.sh文件。让shell_test.sh文件去包含这个文件。
- shell1.sh
#!/bin/bash
url="www.baidu.com"
- shell_test.sh
#!/bin/bash
source ./test1.sh
echo "address: ${url}"
$./shell_test.sh
address: www.baidu.com
判断上一个命令是否执行成功
使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败.
if [ $? -eq 0 ];then
echo "failed"
else
echo "succeed"
fi
结尾
这篇文章是 https://www.runoob.com/linux/linux-shell.html 平台的总结,例子自己举的。
喜欢的可以点个赞,加个关注。
网友评论