blog-web/source/_posts/linux/2.1、shell编程(2)-从入门到重新入门.md
2018-05-10 09:47:30 +08:00

219 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 2.1、shell编程(2)-从入门到重新入门
date: 2018-5-5 00:52:22
tags:
- linux
- shell
categories:
- linux
---
### 传参
在外部执行时可以给脚本传参
在脚本当中获取时 , `$0`是执行的文件路径
`$1`代表第一个参数 , `$2`代表第二个参数 , 以此类推
<!-- more -->
```bash
echo "当前文件:$0"
echo "第一个参数:$1"
#参数个数
echo "共传入$#个参数"
#遍历所有的参数
for arg in $@
do
echo $arg
done
#脚本运行进程的ID
echo "PID:$$"
```
执行脚本
```bash
./test.sh aa bb
#如果参数内容包含空白, 要加引号才能作为一个参数传递
./test.sh aa "bb cc"
```
#### 变量的判断
对于shell脚本来说 , 传参通常是比较灵活的
所以经常需要判断是否传入了这个参数
```bash
if [ -n "$1" ]
then
echo "包含第一个参数"
else
echo "未包含第一个参数"
fi
```
这是判断某个变量是否有值的方式
因为解释型语言的语法比较松散 , 对于变量先定义后使用没有严格要求
所以直接使用一个变量而不进行检查可能造成灾难性的后果
### 运算
原生bash对数学运算的支持比较有限
##### 方法1 `$((expression))`
```bash
num1=3
num2=4
echo $((num1+num2))
echo $((num1**num2)) #乘方
```
变量的引用加不加$都可以 , 不能计算浮点数
##### 方法2 `$[expression]`
```bash
num1=3
num2=4
echo $[num1+num2]
```
变量的引用加不加$都可以 , 不能计算浮点数
##### 方法3 `let`关键字
```bash
num1=3
num2=4
let sum=$num1+$num2
echo $sum
```
变量的引用加不加$都可以 , 不能计算浮点数 , 加号两端不能有空格
##### 方法4 使用`expr`
这是一个内建的用于数学运算的命令
需要注意的是运算符两边必须要有空格
```bash
expr 2 + 6
expr 4 - 9
#注意为了防止歧义 乘法要写 \* 而不能直接写 *
expr 5 \* 4
#除法保留整数
expr 9 / 2
#取余
expr 9 % 2
#浮点数计算
expr "3.9 + 1.8"|bc
#scale表示保留到的小数位数
expr "scale=3;1.2 * 8.73"|bc
```
#### 关系运算
bash当中原生支持关系运算
比较是否相等
```bash
if [ $a == $b ]
then
echo "相等"
fi
if [ $a != $b ]
then
echo "不相等"
fi
```
|运算符|含义|其他表示方式|备注|
|-----|---|---------|
|-eq|是否相等|==|
|-ne|是否不相等|!=|
|-gt|大于|>|
|-lt|小于|<|
|-ge|大于等于|\>=|使用\>=需要使用(( ))|
|-le|小于等于|<=|使用<=需要使用(( ))|
```bash
if [ $a -ge $b ]
then
echo "大于等于"
fi
# 等价于上面的写法, 注意用(( ))
if (( $a >= $b ))
then
echo "大于等于"
fi
```
> 关系运算符只能用于整数 , 或者能够解析为整数的字符串
#### 布尔运算
|运算符|含义|其他表示方式|
|-----|----|---------|
|!|非||
|-o|或|\|\||
|-a|与|&&|
```bash
# a小于10 并且 b大于20
if [ $a -lt 10 -a $b -gt 20 ]
then
echo "yes"
else
echo "no"
fi
# 与上面的含义相同, 但是注意使用[[ ]]
if [[ $a -lt 10 && $b -gt 20 ]]
then
echo "yes"
else
echo "no"
fi
```
> **说明**
> 推荐使用 `[[ ... ]]` 条件判断结构,而不是 `[ ... ]`,能够防止脚本中的许多逻辑错误。比如,&&、|| 操作符能够正常存在于 [[ ]] 条件判断结构中,但是如果出现在 [ ] 结构中的话,会报错。
#### 字符串运算
|运算符|含义|
|----|-----|
|=|两个字符串是否相同(区别于数字的比较)|
|!=|两个字符串是否不相同|
|-z|字符串长度为0返回true|
|-n|字符串长度不为0返回true|
```bash
a="123"
b="456"
if [ $a = $b ]
then
echo "相同"
else
echo "不同"
fi
# 字符串本身也可以用作判断条件
if [ ! $a ]
then
echo "字符串为空"
fi
```
使用`-n``-z`的时候需要注意 , 需要在字符串变量引用上加双引号
```bash
if [ -n "$a"]
then
echo "OK"
fi
```
如果不加双引号 , 当a为空的时候 , 相当于执行
`if [ -n ]` , 这个时候会把里面的**-n**当做一个普通字符串来处理 , 而不是运算符
自然每次都会是true , **-z** 同理
### 文件测试运算符
一个字符串也可以表示一个文件(目录)的路径
使用这些方式可以获得这个文件的各种信息
|运算符|含义|
|------|----|
|-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|
```bash
filepath=/usr/local/test.txt
if [ -e filepath ]
then
echo "文件存在"
else
echo "文件不存在"
fi
```