Skip to main content

Shell 基础知识

Shell 语法

Shell 中的特殊符号

~               Home目录
! 执行历史命令 !! 执行上一条命令
$ 变量中取内容符
+ - * \ % 对应数学运算 加 减 乘 除 取余数
& 后台执行
* shell中的通配符 匹配所有
? shell中的通配符 匹配除回车以外的一个字符
; 分号可以在shell中一行执行多个命令,命令之间用分号分割
| 管道符 上一个命令的输出作为下一个命令的输入
\ 转义字符
`` 反引号 命令中执行命令
' ' 单引号,脚本中字符串要用单引号引起来,但是不同于双引号的是,单引号不解释变量
" " 双引号,脚本中出现的字符串可以用双引号引起来
> 重定向输入 覆盖原数据
>> 重定向追加输入,在原数据的末尾添加
< 重定向输出
<< 重定向追加输出
$? 返回上一条命令的执行结果, 0 成功, !0 失败
expr 只能做整数运算,格式比较古板,注意空格, eg: expr 1 + 1
EOF 左右括号
END 结束
bc,scale (需要单独安装)计算器处理浮点运算, scale=2代表小数点保留两位, eg: echo "scale=2;3+100" | bc
(( )) 双小圆括号运算,在shell中(( ))也可以用来做数学运算, eg: echo $(( 100-3))
exit Number 退出脚本,释放系统资源,Number 代表一个整数,代表返回值, 0 代表正常退出,1代表异常退出

Shell 注释

# 开头的行就是注释,会被解释器忽略。除了#!

单行注释

# 我是注释啊

多行注释

#################
# 注释 😁
# 随便写 😁😁
# 随便写 😁😁😁
#################

EOF也可以用来多行注释:

:<<EOF
注释内容...
注释内容...
注释内容...
EOF
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!

Shell 输入

命令: read

从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量reply.

参数列表

-p: 打印信息 -t: 限定时间 -s: 不回显 -n: 输入字符个数

#!/usr/bin/bash

ehco "Login:"
read LOGIN
read -p -s "Password:"
read PWD

echo "welcome, `$LOGIN`"

Shell 输出

命令: printf

使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认printf不会像 echo 自动添加换行符,我们可以手动添加 \n

printf 的转义序列

序列说明
\a警告字符,通常为ASCII的BEL字符
\b后退
\c抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f换页(formfeed)
\n换行
\r回车(Carriage return)
\t水平制表符
\v垂直制表符
\一个字面上的反斜杠字符
\ddd表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd表示1到3位的八进制值字符

命令: echo

用于在shell中打印shell变量的值,或者直接输出指定的字符串。

参数列表

-e: 转义字符

使用-e选项时,若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:

  • \a 发出警告声
  • \b 删除前一个字符
  • \c 最后不加上换行符号
  • \f 换行但光标仍旧停留在原来的位置
  • \n 换行且光标移至行首
  • \r 光标移至行首,但不换行
  • \t 插入tab
  • \v\f相同
  • \\ 插入\字符
  • \nnn 插入nnn(八进制)所代表的ASCII字符

打印带有色彩的文字

文字色

echo -e "\e[1;31mThis is red text\e[0m"
  • \e[1;31m 将颜色设置为红色
  • \e[0m 将颜色重新置回

颜色码

0 重置30 黑色31 红色
32 绿色33 黄色35 洋红
36 青色37 白色

背景色

echo -e "\e[1;42mGreen Background\e[0m"

颜色码

0 重置40 黑色41 红色
42 绿色43 黄色44 蓝色
45 洋红46 青色47 白色

文字闪动

echo -e "\033[37;31;5mMySQL Server Stop...\033[39;49;0m"

红色数字处还有其他数字参数

0 关闭所有属性1 设置高亮度(加粗)4 下划线
5 闪烁7 反显8 消隐

Shell 输入/输出重定向

输入重定向

TODO:

输出重定向

重定向命令列表

命令说明
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)

/dev/null 文件

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃。

Shell 变量

变量类型

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

  • 局部变量: 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
  • 环境变量: 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  • shell 变量: shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

变量命名

变量名的命名须遵循如下规则:

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线_
  • 不能使用标点符号
  • 不能使用bash里的关键字

变量使用

使用一个定义过的变量,只要在变量名前面加美元符号$即可。

只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

#!/usr/bin/bash
NAME="Rain120"
readonly NAME
NAME="Rainy"

全局变量

使用export `命令可以定义全局变量。语法:

export NAME='Rain120'

删除变量

使用unset命令可以删除变量。语法:

$ unset NAME

Shell 传递参数

在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n

n 代表一个 数字1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

特殊字符参数列表

参数处理说明
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

$*$@ 区别:

  • 相同点:都是引用所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1, 2, 3,则 * 等价于"1 2 3" (传递了一个参数),而 @ 等价于 "1" "2" "3"(传递了三个参数)。
#!/usr/bin/bash
echo -n $0, $1, $2

Shell 字符串

字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。

单引号

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行), 但可成对出现,作为字符串拼接使用
NAME='Rain120'

双引号

  • 双引号里可以有变量
  • 双引号里可以出现转义字符
NAME="Rain120"
# 使用双引号拼接
greeting="hello, "$NAME" !"
greeting_1="hello, ${NAME} !"
echo $greeting $greeting_1

拼接字符串

NAME="Rain120"
# 使用双引号拼接
greeting="hello, "$NAME" !"
greeting_1="hello, ${NAME} !"
echo $greeting $greeting_1
# 使用单引号拼接
greeting_2='hello, '$NAME' !'
greeting_3='hello, ${NAME} !'
echo $greeting_2 $greeting_3

输出结果

hello, Rain120 ! hello, Rain120 !
hello, Rain120 ! hello, ${NAME} !

字符串长度

NAME="Rain120"
echo ${#NAME} #输出 7

提取字符串

NAME="Rain120"
echo ${string:0:4} # 输出 Rain

查找字符串

INTRODUCTION="My github name is rain120"
echo `expr index "$INTRODUCTION" io` # 输出 4

Shell 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

定义数组

Shell 中,用括号来表示数组,数组元素用 空格 符号分割开。

数组名=(值1 值2 ... 值n)

例如

array_name=(value0 value1 value2 value3)
array_name=(
value0
value1
value2
value3
)

还可以单独定义数组的各个分量:

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

可以不使用连续的下标,而且下标的范围没有限制。

使用数组

读取数组元素值:

${数组名[下标]}

使用 @ 符号可以获取数组中的所有元素。

${数组名[@]}

获取数组长度

获取数组长度的方法与获取字符串长度的方法相同。

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

Shell 流程

if

while

util

for

case

Shell 函数

特殊字符参数列表

参考资料

Shell 脚本

Linux命令大全

Linux Vim