shell入门


shell 脚本

以 bash 为例

#! /bin/bash
# bash 的shell文件的开头

# 使用 # 可进行单行注释
:<< EOF
以此格式可
进行多行注释
EOF可换成其他字符
EOF

Hello world!

#! /bin/bash
echo "Hello world!"

变量

定义变量

name1='kyleten'
name2="kyleten"
name3=kyleten # 三种定义方式均可

使用变量

使用变量需要加上$或者${},{}是为了帮助命令解释器识别变量边界

#! /bin/bash
name=kyleten #定义变量name为kyleten
echo $name # 输出kyleten

只读变量

运用readonly或者declare将变量变为只读

name=kyleten
readonly name
declare -r name # 两周写法均可

设置为只读变量的值不能被改变

删除变量

unset name # 删除name

删除命令,unset 命令不能删除只读变量

变量类型

运行 shell 时,会同时存在三种变量:

  1. 局部变量(仅在当前 shell 实例)
  2. 环境变量
  3. shell 变量

默认变量

执行 shell 脚本时,可以向脚本传递参数:$0时文件名(含路径);$1是第一个参数;$2是第二个参数;以此类推.

#! /bin/bash
echo $0 # 输出文件名
echo "第一个参数是:"$1

其他相关变量

变量名说明
$#文件传入参数的个数
$*将所有参数构成以空格隔开的字符串
$@将每个参数分别作为字符串输出,中间用空格隔开
$$脚本当前运行的进程 ID
$?显示上一条命令的退出状态(exit code),0 表示正常
$(command)输出command的正常输出状态(stdout)(可嵌套)
`command`输出command的 stdout(不可嵌套)

数组

shell 脚本仅支持一维数组,初始化时无需指明数组大小,下标从 0 开始

定义

数组用小括号表示,每个元素之间用空格隔开

array=(0 kyleten "az")

也可以直接定义某个元素的值

array[0]=0
array[1]=kyleten
array[2]="az"

读取某个元素的值

格式:

$array[index]

array=(0 kyleten "az")
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}

读取整个数组

格式:

${array[@]}
${array[*]} # 两种写法均可

数组长度

格式:

跟字符串类似

${#array[@]}
${#array[*]} # 两种写法均可

read

输入参数,-p:后跟提示信息;-t:后面跟秒数,定义输入字符的等待时间

read -p "Please input your name:" -t 30 name # 输入你的名字,等待30秒

echo

用于输出字符串

格式:

echo <string>

echo -e 启用\n 转义

printf

类似于c/c++中的printf

格式:

printf format-string [arguments...]

test

用于判断文件类型,以及对变量做比较;test命令用exit code作为返回结果, 0 表示真,非 0 为假 []test用法几乎一致,[]中每一项须用空格隔开,变量最好用双引号括起来,常量用单引号/双引号括起来 例如:

test 2 -lt 3 # 为真,返回值为0
# 也可写成 [ 2 -lt 3 ]
echo $? # 输出上一命令的返回值,为0

文件类型判断

&&||短路原则 在a && b中, a 为 假 ,则忽略 b 在a || b中, a 为 真 ,则忽略 b

测试参数表示意义
-e文件是否存在
-d是否为目录
-f是否为文件

例如:

test -e test1.sh && echo "exist" || echo "not exist"

文件权限判断

格式:

test -r filename # 判断文件是否可读
测试参数表示意义
-r文件是否可读
-w文件是否可写
-x文件是否可执行
-s文件内是否为非空

整数间比较

格式:

test $a -eq $b # a 是否等于 b
测试参数表示意义
-eqa 是否等于 b
-nea 是否不等于 b
-gta 是否大于 b
-lta 是否小于 b
-gea 是否大于等于 b
-lea 是否小于等于 b

字符串比较

测试参数表示意义
test -z string判断 string 是否为空,如果为空,则返回 true
test -n string判断 string 是否为非空,如果为非空,则返回 true(-n 可省略)
test str1 == str2判断 str1 是否等于 str2
test str1 != str2判断 str1 是否不等于 str2

多重条件判定

格式:

test -r filename -a -x filename
测试参数表示意义
-a两条件是否同时成立
-o两条件是否至少一个成立
!取反.如 test ! -x file,当 file 不可执行时,返回 true

判断语句

if

if…then 形式 类似于c/c++中的if-else语句 基础(if-then)

if condition
then
		语句1
		语句2
		...
fi

单层(if-else)

if condition
then
		语句1
		语句2
		...
else
		语句1
		语句2
		...
fi

多次(if-elif-elif-else)

if condition
then
		语句1
		语句2
elif
then
		语句1
		语句2
elif
then
		语句1
		语句2
else
		语句1
		语句2
		...
fi

switch

类似于c/c++中的switch

格式:

case $变量名称 in
	值1)
			语句1
			语句2
			...
			;; # 类似于c/c++中的break
	值2)
			语句1
			语句2
			...
			;;
	*) # 类似于c/c++中的default
			语句1
			语句2
			...
			;;
	esac

循环语句

for…in…do…done

格式:

for var in val1 val2 val3
do
		语句1
		语句2
		...
done

for((…;…;…))do…done

格式:

for((expression;condition;expression))
do
		语句1
		语句2
		...
done

while…do…done

格式:

while condition
do
		语句1
		语句2
		...
done

until…do…done

格式:

until condition
do
		语句1
		语句2
done

break

c/c++基本一致,但无法跳出case语句

continue

c/c++完全一致

函数

类似于c/c++中的函数,但返回值为exit code,取值为 0-255

格式:

[function]func_name(){ # 可省略[function]
		语句1
		语句2
		...
}

fuc_name
# 调用函数格式

文件重定向

每个进程默认打开 3 个文件描述符

  • stdin标准输入,从命令行读取数据,文件描述符为 0
  • stdout标准输出,从命令行输出数据,文件描述符为 1
  • stderr标准错误输出,从命令行输出数据,文件描述符为 2
重定向命令说明
command>filestdout重定向到file
command<filestdin重定向到file
command>>filestdout以追加方式重定向到file
command n>file将文件描述符n重定向到file
command n>>file将文件描述符n以追加方式重定向到file

引入外部脚本

类似于c/c++include操作,bash也可以引入其他文件中的代码 格式:

. filename # 注意点和文件名之间有一个空格



source filename