Shell脚本学习第一天
第一个Shell脚本
1 | echo "打印是内容" //输出内容到stdou 使用双引号"" |
变量
- 定义变量
varName="value",变量名和等号不能有空格 - 首字符(a-z,A-Z)
- 中间不能有空格,可以使用下划线
- 不能使用标点符号
- 不能使用bash里的关键字
For example:
myUrl="http://yutiya.com/"myNum=100
使用变量,在变量名前面加$符号即可
变量名外面的花括号是可选的,是个好习惯
1 | your_name="yutiya" |
如果不写,像下面这样,就会有问题…
1 | for skill in Ada Coffe Action Java |
这里稍微提一下,Shell中使用#打头备注后面的内容,首行特殊表示用什么脚本解析器执行
- 重新定义变量
1 | myUrl="http://yutiya.com/" |
- 只读变量
- 使用readonly命令定义为只读
1 | #!/bin/bash |
赋值报错:
- 删除变量
unset myUrl
1 | #!/bin/bash |
没有输出任何内容
特殊变量
$ ehco $$,打印当前Shell进程的ID,即pid
$0,当前脚本的文件名$n,传递给脚本或函数的参数,n为数字,表示第几个参数$#,传递给脚本或函数的参数个数$*,传递给脚本或函数的所有参数$@,传递给脚本或函数的所有参数,被双引号””包含时,与$*不同$?,上个命令的退出状态,或函数的返回值$$,当前Shell进程ID.对于Shell脚本,就是这些脚本所在的进程ID
For example:
1 | #!/bin/bash |

- $*和$@的区别:
1 | #!/bin/bash |

可以看出来,使用变量的时候如果采用双引号””形式,$@会自动换行
$ echo "上一次命令的退出状态" $?,一般情况下成功为0,失败为1.也可以表示函数返回值
变量替换,命令替换,转义字符
- 转义字符:
1 | a=10 |
加上-e会把\n解析为换行,否则就直接打印\n
\\反斜杠\a警报\b退格\f换页\n换行\r回车\t水平制表符(tab键)\v垂直制表符
-E选项禁止转义,默认不转义,-n禁止插入换行符
- 命令替换(Shell先执行命令,将输出结果暂时保存,在适当的地方输出)
语法:`command`,这里是反引号,tab键上面那个
1 | #!/bin/bash |

- 变量替换:
| 形式 | 说明 |
|---|---|
| ${var}` | 变量本来的值 |
| ${var:-word} | 如果变量var为空或已被删除,那么返回word,但不改变var的值 |
| ${var:=word} | 如果变量var为空或已被删除,那么返回word,并将改变var的值 |
| ${var:?message} | 如果变量var为空或已被删除,那么将消息messgae送到标准错误输出,可以用来检测变量var是否可以被正常赋值,若此替换出现在Shell脚本中,那么脚本将停止运行 |
| ${var:+word} | 如果变量var被定义,那么返回word,但不改变var的值 |

Shell运算
expr:表达式计算工具
1 | #!/bin/bash |
输出结果:Total value: 4
注意:
- 变量和运算符之间要有空格,
2 + 2 - 使用反引号进行命令替换,tab上面的按键
For example:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi

| 运算符 | 说明 |
|---|---|
| + | 加法 |
| - | 减法 |
| * | 乘法 |
| / | 除法 |
| % | 取余 |
| = | 赋值 |
| == | 相等.用于比较两个数字,相同则返回true |
| != | 不相等.用于比较两个数字,不相同则返回true |
- 关系运算(只支持数字,不支持字符串,除非字符串的值是数字):
1 | #!/bin/bash |

| 运算符 | 说明 |
|---|---|
| -eq | 检测两个数是否相等,相等返回true |
| -ne | 检测两个数是否相等,不相等返回true |
| -gt | 检测左边的数是否大于右边的,如果是,则返回true |
| -lt | 检测左边的数是否小于右边的,如果是,则返回true |
| -ge | 检测左边的数是否大于等于右边的,如果是,则返回true |
| -le | 检测左边的数是否小于等于右边的,如果是,则返回true |
- 布尔运算符:
1 | #!/bin/bash |
| 运算符 | 说明 |
|---|---|
| ! | 非运算,表达式为true则返回false,否则返回true |
| -o | 或运算,有一个表达式为true则返回true |
| -a | 与运算,两个表达式都为true才返回true |
- 字符串运算符:
1 | #!/bin/bash |

| 运算符 | 说明 |
|---|---|
| = | 检测两个字符串是否相等,相等返回true |
| != | 检测两个字符串是否相等,不相等返回true |
| -z | 检测字符串长度是否为0,为0返回true |
| -n | 检测字符串长度是否为0,不为0返回true |
| str | 检测字符串是否为空,不为空返回true(直接判断变量) |
- 文件测试运算符:
检测unix文件的各种属性
1 | #!/bin/bash |

| 操作符 | 说明 |
|---|---|
| -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 |
Shell字符串
- 单引号:
str='this is a string'
注意:
- 单引号里的任何字符都会原样输出,使用的变量无效
- 单引号字符串中不能出现单引号(对单引号使用转义符后也不行)
- 双引号:
str="Hello, I know you are \"$your_name\"! \n",可以使用变量,可以出现转义字符 - 字符串拼接
1 | your_name="yutiya" |
- 获取字符串长度
1 | string="abcd" |
- 取子字符串
1 | string="alibaba is a great company" |
- 查找子字符串
注意: mac终端的expr命令只能进行加减乘除
1 | string="alibaba is a great company" |
数组
1 | array_name=(value0 value1 value2 value3) |
可以不使用连续的下标,而且下标的范围没有限制
读取:
1
- 获取所有元素:```${array_name[*]}```或者```${array_name[@]}
获取数组的长度:
1
- 取得数组单个元素的长度:```length=${#array_name[n]}
echo
- 普通
$ echo arg - 转义
$ echo "\" It is a test \"" - 变量
$ echo "$name is a number",变量与其他字符相连请加上${name} - 换行
$ echo "Oh! \n" - 不换行
$ echo "OK! \c" - 结果输出到文件
$ echo "test" > filename - 原样输出
$ echo 'chars' - 显示命令结果
`date`
双引号可有可无,单引号原样输出