美文网首页
Shell 基础知识点总结

Shell 基础知识点总结

作者: 付凯强 | 来源:发表于2021-11-08 20:46 被阅读0次

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

特点:

  1. 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的。
  2. 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
#!/bin/bash

str="HelloWorld!"
echo '${str}'
$./shell_test 
${str}

双引号字符串

#!/bin/bash

str="HelloWorld!"
echo "fkq \"${str}\""
$./shell_test 
fkq "HelloWorld!"

特点:

  1. 双引号里可以有变量
  2. 双引号里可以出现转义字符

拼接字符串

#!/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

注意:

  1. 2 + 1 的 + 号两边都要有空格.
  2. expr表达式要用反引号 ` 括起来,而不是单引号 '
  3. 乘号(*)前边必须加反斜杠()才能实现乘法运算
  • [ ]
    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中,调用函数时可以向其传递参数。在函数体内部,通过 n 的形式来获取参数的值,例如,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 输入/输出重定向

有以下几个符号,可以实现输入或者输出重定向。这里重点说下符号 ">" 和 "<"。

  1. command > file 将输出重定向到文件
  2. command < file 将输入重定向到文件
  3. command >> file 将输出以追加的方式重定向到 file
  4. n > file 将文件描述符 n 重定向到文件
  5. n >> file 将文件描述符 n 以追加的方式重定向到文件
  6. n >& m 将输出文件m和n合并
  7. n <& m 将输入文件m和n合并
  8. << 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。
注意:

  1. 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
  2. 开始的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 平台的总结,例子自己举的。
喜欢的可以点个赞,加个关注。

相关文章

  • Shell 基础知识点总结

    Android源码的编译环节涉及很多Shell脚本,以及在Android.mk中也大量使用了Shell命令。为了能...

  • Linux Shell: 各种tips

    通用Linux中执行shell脚本的4种方法总结hbase shell基础和常用命令详解 2.字符串Shell脚本...

  • 2018-10-11

    10月11日任务 8.1shell介绍 shell有基础以及脚本 tab补全命令 快捷方式 本章总结之前的命令 s...

  • 《第一行代码》---Android 啃完,学习笔记

    #Android 基础知识点总结 ---------- ##1.adb - android debug bridg...

  • 完结篇

    至此,Python基础知识基本就这些了 后面会进行知识点总结

  • Linux Shell:基础知识和Shell变量

    摘要:Linux,Shell 整理Shell内容要点: Shell基础知识 Shell变量的类型 Shell变量赋...

  • Unity基础【唐老狮】(一)3D数学基础,向量

    Unity基础 概述&个人总结 基础知识点 3D数学-基础 基础数学函数 插值运算Lerp:根据系数输出中间值先快...

  • 机器学习算法——朴素贝叶斯

    参考书籍地址 基础公式 算法过程讲解 知识点总结 例题 1.先来复习一下几个公式: 2.算法过程 3.知识点总结 ...

  • day 28

    shell编程基础 shell编程一小时光速入门web集群架构会用到shell编程基础 1、为什么要学shell编...

  • Java原理学习总结

    本文主要是我最近复习Java基础原理过程中写的Java基础学习总结。Java的知识点其实非常多,并且有些知识点比较...

网友评论

      本文标题:Shell 基础知识点总结

      本文链接:https://www.haomeiwen.com/subject/nkjvqktx.html