Linux Shell编程
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
bash通配符介绍
通配符允许您简洁地指定用于匹配一组文件名的模式(例如,*.pdf 模式可以获得所有 PDF 文件列表)。通配符通常也被称为 glob 模式。但是,glob 模式的用途不仅仅只能生成一个有用的文件名列表。Bash man 帮助页面中将 glob 模式简单地称为 “Pattern Matching(模式匹配)”。
通配符 | 描 述 |
---|---|
* | 匹配任意长度的任何字符串,包括空字符串 |
? | 匹配任何单个字符 |
[…] | 匹配在指定字符范围内任何单个字符,简化写法[a-z]不区分大小写 |
?(pattern-list) | 匹配零个或一个指定模式的匹配项(extglob) |
*(pattern-list) | 匹配零个或更多指定模式的匹配项(extglob) |
+(pattern-list) | 匹配一个或更多指定模式的匹配项(extglob) |
@(pattern-list) | 匹配其中一个指定模式的匹配项(extglob) |
!(pattern-list) | 匹配任何不匹配指定模式的项目(extglob) |
[^] | 匹配指定字符范围外的任意单个字符 |
部分已经设置好的字符类:
字符类 | 说明 |
---|---|
[:alnum:] | 所有字母和数字 |
[:alpha:] | 所有字符,包括大小写 |
[:blank:] | 所有水平空白字符 |
[:cntrl:] | 所有控制字符(不可打印) |
[:digit:] | 所有数字,等价于 [0-9] |
[:graph:] | 所有图形字符 |
[:lower:] | 所有小写字符 |
[:print:] | 所有可打印字符 |
[:punct:] | 所有标点符号 |
[:space:] | 所有水平和垂直空格 |
[:upper:] | 所有大写字符 |
[:xdigit:] | 所有十六进制字符 |
Tab Tab | 显示文件或命令补全的可能性 |
1
2
3
4
5
6
7
8
9
10
# 列出a开头的所有文件
ls a*
# 列出a开头一共3个字母的文件
ls a??
# 列出三个大写字母文件名的文件
ls [[:upper:]][[:upper:]][[:upper:]]
# 列出一个字母后跟三个数字的文件
ls [a-z][0-9][0-9][0-9]
# 列出不以a字母开头后跟三个数字的文件
ls [^a][0-9][0-9][0-9]
拓展:Bash中的组合键
键或组合键 | 功能 |
---|---|
Ctrl+A | 将光标移动到命令行开头 |
Ctrl+C | 结束正在运行的程序并返回提示符 |
Ctrl+D | 退出当前shell会话,相当于键入exit或logout |
Ctrl+E | 将光标移动到命令行末尾 |
Ctrl+H | Generate backspace character |
Ctrl+L | Clear this terminal |
Ctrl+R | 查询命令历史记录 |
Ctrl+Z | 暂停一个程序 |
ArrowLeft and ArrowRight | 将光标在命令行上向左或向右移动一个位置,这样就可以在其他位置插入字符,而不仅仅是在开头和结尾 |
ArrowUp and ArrowDown | 浏览历史。转到要重复的行,如果需要编辑详细信息,按Enter键以节省时间 |
Shift+PageUp and Shift+PageDown | 浏览终端缓冲区(查看已“滚屏”的文本) |
Tab | 命令或文件名补全;当有多种选择时,系统会发出声音或视觉铃声,如果选择太多,则会询问你是否都想看 |
Tab Tab | 显示文件或命令补全的可能性 |
Shell脚本
Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动、挂起、停止甚至是编写一些程序。
脚本的编写和执行
- 脚本格式要求:
- 1.脚本以
#!/bin/bash
开头,指定其解释器 - 2.脚本需要有可执行权限
- 1.脚本以
- 脚本常用的执行方式:
- 1.赋予脚本x权限,然后输入脚本的绝对路径或者相对路径执行,如
./hello.sh
- 2.指定sh,直接执行,如
sh hello.sh
或者bash hello.sh
- 1.赋予脚本x权限,然后输入脚本的绝对路径或者相对路径执行,如
1
2
#!/bin/bash
echo "hello,world"
Shell的变量
介绍
- Linux Shell的变量分为
系统变量
和用户自定义变量
- 系统变量:
$HOME
、$PWD
、$SHELL
、$USER
等 - 显示当前shell中所有的变量:
set
变量定义
基本语法
1
2
3
4
5
6
# 定义变量
变量=值
# 撤销变量
unset 变量
# 声明静态变量,这种变量不能unset
readonly 变量
注意事项:
等号两侧不能有空格
变量名称严格区分大小写,一般大写
变量名称可由字母数字下划线组成,不可以数字开头
将命令的返回值赋给变量
1
2
3
4
# 反引号,运行里面的命令,并把结果返回给变量A
A=`date`
# 等价于反引号
A=$(date)
环境变量的设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将shell变量输出为环境变量/全局变量
export 变量名=变量值
# 让修改后的配置信息立即生效
source 配置文件
# 查询环境变量的值
echo $变量名
# 输出所有环境变量,包括全局变量、局部变量
set
# 输出全局环境变量
env
#删除变量或函数
unset 变量名
位置参数变量
如果希望获取到命令行的参数信息,就可以使用位置参数变量
基本语法
$n
:n为数字,$0为命令本身,$1-$9代表第1到9个参数,10以上需要用大括号,如${10}$*
:代表命令行中所有的参数,整体看待$@
:代表命令行中所有的参数,区分看待,使用双引号"
包含时可以明显看到区别$#
:代表命令行中所有参数的个数
预定义变量
shell设计者事先已经定义好的变量
$$
:当前进程的进程号(PID)$!
:后台运行的最后一个进程的进程号(PID)$_
:上次命令传递的最后一个参数$?
:最后一次执行的命令的返回状态
这个变量的值为0,那么上一个命令正确执行,如果非0则不正确
拓展变量
- result=${parameter:-word} 如果parameter为空,则word赋值给result,否则输出parameter
- result=${parameter:=word} 如果parameter为空,则word赋值给result和parameter,否则输出parameter
- result=${parameter:?word} 如果parameter为空,则word当做stderr输出,否则输出parameter
- result=${parameter:+word} 如果parameter为空,什么都不做,否则word赋值给result
字符串
字符串(String)就是一系列字符的组合。字符串是 Shell 编程中最常用的数据类型之一(除了数字和字符串,也没有其他类型了)。
字符串有三种形式:
- 由单引号
' '
包围的字符串:- 任何字符都会原样输出,在其中使用变量是无效的。
- 字符串中不能出现单引号,即使对单引号进行转义也不行。
- 由双引号
" "
包围的字符串:- 如果其中包含了某个变量,那么该变量会被解析(得到该变量的值),而不是原样输出。
- 字符串中可以出现双引号,只要它被转义了就行。
- 不被引号包围的字符串
- 不被引号包围的字符串中出现变量时也会被解析,这一点和双引号” “包围的字符串一样。
- 字符串中不能出现空格,否则空格后边的字符串会作为其他变量或者命令解析。
1
2
3
4
5
6
# 强引用,将字符串$(date)赋值给A
A='$(date)'
# 识别特殊符号,弱引用,将命令date的结果赋值给A
A="$(date)"
# 将命令date的结果赋值给A,连续的符号可使用,有空格则有歧义
A=$(date)
字符串拼接(连接、合并)
在 Shell 中你不需要使用任何运算符,将两个字符串并排放在一起就能实现拼接。请看下面的例子:
1
2
3
4
5
str1=$A$B #中间不能有空格
str2="$A $B" #如果被双引号包围,那么中间可以有空格
str3=$A": "$B #中间可以出现别的字符串
str4="$A: $B" #这样写也可以
str5="${A}is: ${B}" #如果有字符串,需要给变量名加上大括号
字符串截取
格式 | 说明 |
---|---|
${变量} | 返回变量值 |
${#变量} | 返回变量长度,字符长度 |
${变量:start} | 从变量的左边第 start 个字符开始截取,直到最后。start 为正整数 |
${变量:start:length} | 从变量的左边第 start 个字符开始,向右截取 length 个字符。 |
${变量:0-start} | 从变量的右边第 start 个字符开始截取,直到最后。 |
${变量:0-start:length} | 从变量的右边第 start 个字符开始,向右截取 length 个字符。 |
${变量#word} | 从变量开头,删除最短匹配的word |
${变量##word} | 从变量开头,删除最长匹配的word |
${变量%word} | 从变量结尾开始,删除最短匹配的word |
${变量%%word} | 从变量结尾开始,删除最长匹配的word |
${变量/pattern/string} | 用 string 代替第一个匹配的 pattern。 |
${变量//pattern/string} | 用 string 代替所有 pattern。 |
多行注释
1
2
3
:<<!
注释内容
!
运算符
基本语法
$((运算式))
或$[运算式]
或expr m + n
- 注意
expr
运算符间要有空格,如果希望将expr
的结果赋给变量,使用反引号 - 乘:
\*
(在使用exp
r时需要转义)
除:/
取余:%
条件判断
基本语法 [ condition ]
(注意前后要有空格)
只要非空即返回true
常用判断条件
- 字符串比较(
=
) - 两个整数的比较
-lt
(小于)-le
(小于等于)-eq
(等于)-gt
(大于)-ge
(大于等于)-ne
(不等于)
- 按照文件权限进行判断
-r
(有读的权限)-w
(有写的权限)-x
(有执行的权限)
- 按照文件类型进行判断
-f
(文件存在并且是一个常规文件)-e
(文件存在)-d
(文件存在并是一个目录)
流程控制
if判断
1
2
3
4
if [ 条件判断式 ]
then
代码
fi
1
2
3
4
5
6
7
if [ 条件判断式 ]
then
代码
elif [ 条件判断式 ]
then
代码
fi
case语句
1
2
3
4
5
6
7
8
9
10
11
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
for循环
1
2
3
4
for 变量 in 值1 值2 值3...
do
代码
done
1
2
3
4
for ((初始值:循环控制条件:变量变化))
do
代码
done
while循环
1
2
3
4
while [ 条件判断式 ]
do
代码
done
read读取控制台输入
基本语法
1
read [选项] 参数
选项
-p
指定读取值时的提示符-t
指定读取值时等待的时间(s)- 参数:指定变量名
系统函数
basename [pathname] [suffix]
返回完整路径最后/的部分,常用于获取文件名,suffix为后缀,如果指定了会把结果中的suffix去掉dirname [pathname]
返回完整路径最后/之前的部分,常用于返回路径部分
自定义函数
基本语法
1
2
3
4
5
[ function ] funname[()]
{
Action;
[return int;]
}
调用的时候 funname [值]
本文参考
本文由作者按照 CC BY 4.0 进行授权