--- title: 2.1、shell编程(2)-从入门到重新入门 date: 2018-5-5 00:52:22 tags: - linux - shell categories: - linux --- ### 传参 在外部执行时可以给脚本传参 在脚本当中获取时 , `$0`是执行的文件路径 `$1`代表第一个参数 , `$2`代表第二个参数 , 以此类推 ```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 ```