shell基础理论
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
shell环境
- Bourne shell(/user/nbin/sh或/bin/sh)
 - Bourne Again Shell (/bin/bash)
 - C Shell (/usr/bin/csh)
 - K Shell (/usr/bin/ksh)
 - Shell for Root (/sbin/sh)
 
脚本运行方法
作为可执行程序
编写脚本,使用.sh后缀保存(#!/bin/bash 写在第一行标记解释器形式)
1
2chmod +x ./test.sh #使脚本具有运行权限
./test.sh #运行脚本
使用./说明在当前目录下寻找脚本文件,如果没有./那么会在系统路径中寻找
作为解释器参数
运行解释器,参数为shell脚本名,如
1  | /bin/sh test.sh  | 
Shell基础语法汇总
变量
定义变量
变量名不加美元符号(PHP中需要)
1  | name="shell"  | 
- 变量名和等号之间不能有空格
 - 可以用循环语句赋值
 
使用变量
输出
1
2echo $name
echo ${name} #{}界定范围只读
1
2name="shell"
readonly name此时name变量不可被修改,运行脚本报错
1
/bin/sh: NAME: This variable is read only.
删除变量
1  | unset name  | 
变量被删除后不能再次使用,unset命令不能删除只读变量
变量类型
- 局部变量:当前shell中有效
 - 环境变量:所有程序都可访问
 - shell变量:shell程序设置的变量,部分局部部分环境
 
字符串
定义
单引号:
- 字符原样输出,单引号内变量无效;
 - 单引号字符串中不能出现单独的单引号,转义也不行,但是可以在字符串拼接的时候成对使用
 
双引号
双引号内可以有变量
可以有转义字符
1
2name='shell'
str="Hello, I know you are \"$name\"! \n"
拼接
双引号
1
2
3greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
两种表示均可以正确输出单引号
1
2
3greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
单引号内变量无效,后一种表示原样输出字符串
长度
1  | name="shell"  | 
子字符串
截取
1
2
3
4
5
6
7
8
9
10指定位置截取
string="shell"
echo ${string:1:3} # 输出 hel
截取子字符串后字符串
{varible##*string} #从左向右截取最后一个string后的字符串
{varible#*string} #从左向右截取第一个string后的字符串
{varible%%string*} #从右向左截取最后一个string后的字符串
{varible%string*} #从右向左截取第一个string后的字符串
*只是一个通配符可以不要查找
1
2string="shell"
echo `expr index "$string" sa` # 查找字符s或a第一个出现的位置,输出 1,使用反引号
数组
1  | array_name=(a b c d)  | 
注释
1  | --------------------------------------------  | 
传递参数
基础示例
在运行脚本时即向脚本中传递某些参数,这些参数以$n的格式获取,n=0时为文件名,n=1……时为参数
例:向test.sh中传递三个参数1 2 3
脚本如下
1  | echo "Shell 传递参数实例!";  | 
命令如下
1  | $ chmod +x test.sh  | 
输出如下
1  | Shell 传递参数实例!  | 
其他特殊字符处理
| 字符 | 说明 | 
|---|---|
| $# | 传递到脚本的参数个数 | 
| $* | 以一个单字符串显示所有向脚本传递的参数。 如”$*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。相当于一个字符串  | 
| $! | 后台运行的最后一个进程的ID号 | 
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如”$@”用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数。相当于n个字符串  | 
| $- | 显示Shell使用的当前选项,与set命令功能相同。 | 
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 | 
| $$ | 脚本运行的当前进程ID号 | 
基本运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
 - 完整的表达式要被 ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
 
算术运算符
| 运算符 | 说明 | 举例 | 
|---|---|---|
| + | 加 | expr $a + $b | 
| - | 减 | expr $a - $b | 
| * | 乘 | expr $a \* $b | 
| / | 除 | expr $a / $b | 
| % | 取余 | expr $a % $b | 
| = | 赋值 | a=$b | 
| == | 数字相等 | [$a == $b] | 
| != | 数字不相等 | [$a != $b] | 
关系运算符
只支持数字,除非字符串中也是数字
| 运算符 | 说明 | 举例 | 
|---|---|---|
| -eq | == | [ $a -eq $b ] | 
| -ne | != | [ $a -ne $b ] | 
| -gt | > | [ $a -gt $b ] | 
| -lt | < | [ $a -lt $b ] | 
| -ge | >= | [ $a -ge $b ] | 
| -le | <= | [ $a -le $b ] | 
布尔运算符
| 运算符 | 说明 | 举例 | 
|---|---|---|
| ! | 非,取反 | [ ! false ] 返回 true | 
| -o | 或 | [ $a -lt 20 -o $b -gt 100 ] 返回 true | 
| -a | 与 | [ $a -lt 20 -a $b -gt 100 ] 返回 false | 
逻辑运算符
| 运算符 | 说明 | 举例 | ||||
|---|---|---|---|---|---|---|
| && | 与 | [[ $a -lt 100 && $b -gt 100 ]] 返回 false | ||||
| \ | \ | 或 | [[ $a -lt 100 \ | \ | $b -gt 100 ]] 返回 true | 
字符串运算符
| 运算符 | 说明 | 举例 | 
|---|---|---|
| = | 相等 | [ $a = $b ] | 
| != | 不相等 | [ $a != $b ] | 
| -z | 检测长度为0,为0则true | [ -z $a ] | 
| -n | 检测长度为0,不为0则true | [ -n “$a” ] | 
| $ | 判断为空 | [ $a ] | 
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性
| 运算符 | 说明 | 
|---|---|
| -b file [-b $file] | 检测文件是否是块设备文件,如果是,则返回 true | 
| -c file | 检测文件是否是字符设备文件,如果是,则返回 true | 
| -d file | 检测文件是否是目录,如果是,则返回 true | 
| -f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true | 
| -g file | 检测文件是否设置了 SGID 位,如果是,则返回 true | 
| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true | 
| -p file | 检测文件是否是有名管道,如果是,则返回 true | 
| -u file | 检测文件是否设置了 SUID 位,如果是,则返回 true | 
| -r file | 检测文件是否可读,如果是,则返回 true | 
| -w file | 检测文件是否可写,如果是,则返回 true | 
| -x file | 检测文件是否可执行,如果是,则返回 true | 
| -s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true | 
| -e file | 检测文件(包括目录)是否存在,如果是,则返回 true | 
| -S file | 判断某文件是否 socket | 
| -L file | 检测文件是否存在并且是一个符号链接 | 
echo
1  | 普通字符串  | 
printf
printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好
1  | printf format-string [arguments...]  | 
转义序列
| 序列 | 说明 | 
|---|---|
| \a | 警告字符,通常为ASCII的BEL字符 | 
| \b | 后退 | 
| \c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 | 
| \f | 换页(formfeed) | 
| \n | 换行 | 
| \r | 回车(Carriage return) | 
| \t | 水平制表符 | 
| \v | 垂直制表符 | 
| \ | 一个字面上的反斜杠字符 | 
| \ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 | 
| \0ddd | 表示1到3位的八进制值字符 | 
test
数值测试
1  | num1=100  | 
字符串测试
1  | num1="shell1"  | 
文件测试
1  | cd /bin  | 
条件连接
1  | cd /bin  | 
流程控制
if else
1  | if condition1  | 
for
1  | for var in item1 item2 ... itemN  | 
while
1  | int=1  | 
until
1  | until [ ! $a -lt 10 ]  | 
case
1  | case 值 in  | 
函数
1  | 定义  | 
文件包含
. filename 或 source filename
1  | test1.sh  |