woki

该文整理一些常用的shell用法,及语法,并非介绍如何使用

## 变量

变量可分为两类:环境变量ENV(全局)和局部变量。

 bash环境变量

| 变量名                           | 含义                                                         |
| -------------------------------- | ------------------------------------------------------------ |
| _=                               | 上一条命令的最后一个参数                                     |
| BASH_VERSION="4.1.2(1)-release"  | 当前bash实例的版本号                                         |
| COLORS="/etc/DIR_COLORS"         |                                                              |
| COLUMNS=80                       | 设置该变量就给shell编辑模式和选择命令定义了编辑窗口的宽度    |
| CVS_RSH="ssh"                    |                                                              |
| DIRSTACK                         | 代表目录栈当前的内容                                         |
| EUID=0                           | 为在shell启动时被初始化的当前用户的有效ID                    |
| G_BROKEN_FILENAMES=1             |                                                              |
| GROUPS=()                        | 当前用户所属组                                               |
| HISTFILE=/root/.bash_history     | 历史记录文件的全路径                                         |
| HISTFILESIZE=50                  | 历史文件能包含的最大行数                                     |
| HISTSIZE=50                      | 记录在命令行历史文件中的命令行数                             |
| HOME=/root                       | 当前用户家目录                                               |
| HOSTNAME=                        | 当前主机机器名称                                             |
| HOSTTYPE=x86_64                  |                                                              |
| IFS=$'\t\n'                      | 内容字段分隔符,一般是空格符、制表符、和换行符,用于由命令替换,循环结构中的表和读取的输入产生的词的字段划分。 |
| INPUTRC=/etc/inputrc             | readline启动文件的文件名。取代默认的~/.inputrc               |
| JAVA_HOME=/app/jdk1.6            |                                                              |
| KDENIR=/usr                      |                                                              |
| KDE IS PRELINKED=1               |                                                              |
| LANG=zh_CN.GB18030               |                                                              |
| LESSONPEN                        |                                                              |
| LINES=36                         |                                                              |
| LONGNAME=root                    | 登陆的用户名                                                 |
| LS_COLORS=xx                     |                                                              |
| MACHTYPE=x86_64-redhat-linux-gnu | 包含一个描述正在运行bash的系统串                             |
| MAILCHECK=60                     | 这个参数定义shell将隔多长时间(以秒为单位检查一次由参数MAILPATH或MAILFILE)指定的文件,看看是否有邮件到达。默认600秒 |
| MAIL=/var/spool/mail/root        | 邮件全路径                                                   |
| OLDPWD=/root                     | 前一个当前工作目录                                           |
| OPTERR=1                         | 如果设置为1,秒年十时毫,来自getopts内置命令的错误信息。     |
| OPTIND=1                         | 下一个有getopts内置命令处理的参数序号                        |
| OSTYPE=linux-gnu                 | 自动设置称一个串,该串标书正在运行bash的操作系统,默认值有系统决定 |
| PATH                             | 全局PATH路径。命令搜索路径。一个有冒号分隔的目录列表,shell用它来搜索命令。默认路径有系统决定,并且由安装bash的管理员设置。 |
| PIPESTATUS=([0]=0 [1]=1)         | 一个数组,包含一列最进在管道执行的前台作业的进程退出状态值。 |
| PPID=1112                        | 父进程的进程ID                                               |
| PS1=[\u@\h \W]\$                 | 主提示符串,默认值是$                                        |
| PS2= >                           | 次提示符串,默认值是>                                        |
| PS4=+                            | 当开启追踪时使用的调试提示符串,默认值是+,追踪可用set-x开启。 |
| PWD                              | 当前用户家目录。                                             |
| SHELL=/bin/bash                  |                                                              |
| SHLVL=1                          | 每启动一个bash实例就将其加1                                  |
| TMOUT=3600                       | 退出前等待超时的秒数。                                       |
| UID=0                            | 当前用户的UID,在shell启动时初始化。                         |
| USER=root                        | 当前用户的用户名,在shell启动时初始化。                      |

自定义环境变量 `export`

默认的环境变量 `env`(`printenv`)或`set`

消除本地变量和环境变量 `unset `

定义变量:***习惯:数字不加引号,其他默认加双引号***

### 引号

| 名称        | 解释                                                         |
| ----------- | ------------------------------------------------------------ |
| 单引     号 | 可以说是所见即所得:即将单引号内的所有内容都原样输出,或者描述为单引号里面看到的是什么就会输出什么。 |
| 双引号      | 把双引号内的所有内容都输出出来;如果内容中有命令(要反引下)、变量、特殊转义符等,会先把变量、命令解析出结果,然后再输出最终内容来。 |
| 无引号      | 把内容输出出来前,会将含有空格的字符串视为一个整体输出,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容来,如果字符串中带有空格等特殊字符,则不能完整的输出,需要改加双引号,一般连续的字符串,数字,路径等可以不加任何引号,不过无引号的情况最好用双引号替代之。 |
|             |                                                              |

### 变量的命名规范

- **变量名要统一**,使用全部大写字母,如`APCHE_ERR_NUM`;语义要清晰,能够正确表达变量内容含义,过长的英文单词可采用前几个字符代替,多个单词连接用“_”连接,引用时,最好以`${APACHE_ERR_NUM}`或"`${APACHE_ERR_NUM}`"的方式引用变量。

- **避免无意义字符或数字**:例如下面的COUNT,并不知道其确切含义
- 范例1:COUNT的不确切定义  `COUNT=$(grep keywords file)`
- 全局变量和局部变量命名
  - **脚本中的全局变量定义**,如`USER_HOME`或`USERHOME`,在变量使用时,使用 `{ }`将变量括或"`${APACHE_ERR_NUM}"`了;变量后还有字符串隔不开的情况下,用大括号扩一下 `${金庸}`新著作
  - **脚本中局部变量定义**:存在于脚本函数`(function)`中的变量称为局部变量,要以local方式进行生命,使之只在本函数作用域内有效,防止变量在函数中的命名于变量外部程序中变量重名造成程序异常。下面是函数中的变量定义例子:

### 特殊变量

| No       | 位置变量                                                     |
| -------- | ------------------------------------------------------------ |
| **`$0`**   | 当前执行的shell脚本的文件名,如果执行脚本带路径则包括脚本路径。 |
| **`$n` **  | 当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本文件名,如果n大于9用大括号括起来`${10}`. |
| **`$#`**   | 当前执行的shell脚本后面接的参数的总个数                      |
| **`$*`**   | 当前shell的所有传参的参数,将所有的参数视为单个字符串,相当于`“$1$2$3..`”注意$与#的区别 |
| **`$@`**   | 这个程序的所有参数`“$1” “$​2” “$3” ....”`,这是将参数传递给其他程序的最佳方式,因为会保留所有内嵌在每个参数里的任何空白。 |
|          | <font color="red">**进程状态变量**</font>                    |
| **`$$`**   | 获得当前shell脚本的进程号(PID)                             |
| **`$?`** | 执行上一个指令的返回值(0为成功,非0为失败) |
| **`$!`** | 执行上一个指令的PID |
| **`$_`** | 在此之前执行的命令或脚本的最后一个参数。 |

`$?`  返回值参考

| no    | 意思                                                         |
| ----- | ------------------------------------------------------------ |
| 0     | 表示允许成功                                                 |
| 2     | 权限拒绝                                                     |
| 1~125 | 表示运行失败,脚本命令、系统命令错误或参数传递错误           |
| 126   | 找到该命令了,但是无法运行                                   |
| 127   | 为找打要运行的命令`$ zhangsan-bash: zhangsan: command not found` `$ echo $? 127` |
| >128  | 命令被系统强制结束`$ sleep 100000^C` `$ echo $?130` |

### 变量子串

| 表达式          | 说明                                            |
| ------------------------- | --------------------------------------------------------- |
| `${#string}`                | 返回$string的长度                                         |
| `${string:position}`        | 在$string中,从位置$position之后开始提取子串              |
| `${string:position:length}` | 在$string中,从位置position之后开始提取长度为length的子串 |
| `${string#sub}`             | 从变量string开头开始删除最短匹配sub子串                   |
| `${string##sub}`            | 从变量开头开始删除最长匹配子串                            |
| `${string%sub}`             | 从变量string结尾开始删除最短匹配sub子串                   |
| `${string%%sub}`            | 从变量string结尾开始删除最长匹配sub子串                   |
| `${string/sub/rep}`        | 使用rep,来代替第一个匹配的sub                            |
| `${string/#sub/rep}`        | 如果string前缀匹配sub就用rep代替匹配sub                   |

### 变量替换

| 运算符号                  | 替换                                                         |
| ------------------------- | ------------------------------------------------------------ |
| `${value:-word}`          | 如果变量名存在且非null,则返回变量的值。否则,返回word字符串。用途:如果变量未定义,则返回默认值。范例:`${value:-word}`,如果value未定义,则表达式的值为word |
| `${value:=word}`          | 如果变量名存在且非null,则返回变量值。否则,设置这个变量值未word,并返回其值。用途:如果变量未定义,则设置变量为默认值,并返回默认值。范例:`${value:=word}`,如果value未定义,则设置value的值为word,返回表达式的值也为word。 |
| `${value:?"not defined"}` | 如果变量名存在且非null,则返回变量的值。否则显示变量名:msg,并退出当前的命令或脚本。用途:用于捕捉由于变量未定义而导致的错误,并退出程序。范例:`${value:?"not defined"}`如果value未定义,则显示`-bash:value:not defined`并退出。 |
| `${value:+word}`          | 如果变量名存在且非null,则返回word。否则返回null。用途:测试变量是否存在。范例:`${value:+word}` 如果value已经定义,返回word(也是就是真)。 |
|                           |                                                              |

## 数值(整数)计算



###  (( ))

如果要执行简单的整数运算,只需将特定的算数表达式用 `(( ` 和  `))` 括起来即可。

shell的算数运算符号常置于`$((` 和  `))`的语法中。这一语法如同双引号用能,除了内嵌双引号无需转义。

| 运算符                          | 意义                               |
| ------------------------------- | ---------------------------------- |
| ++ --                           | 增加及减少,可前置也可放在结尾     |
| + - !~                         | 一元的正号与负号;逻辑与位的取反   |
| * / %                           | 乘法、除法、与取余                 |
| + -                             | 加法、减法                         |
| < <= > >=                       | 比较负号                           |
| == !=                           | 相等与不相等,一个“=”赋值          |
| << >>                           | 向左位移 向右位移                  |
| &                               | 位的AND                            |
| ^                               | 位的异或                           |
| \|                              | 位的或                             |
| &&                              | 逻辑的AND(make && mak install)   |
| \|\|                            | 逻辑的OR(make \|\| make install) |
| ?:                              | 条件表达式                         |
| = += -= *= /= &= ^= <<= >>= \|= | 赋值运算符 a+=1都相当a=a+1         |

- `**` 为幂运算:`%` 为取模运算(就是除法当中取余数)。
- 上面涉及到的参数变量必须位整数(==整型==)。不能是小数(浮点数)或者字符串。后面的bc命令可以进行浮点数运算,但一般较少用到。
- `echo $((a++))` 和 `$((a--))` 表示先输出a自身的值,然后在进行 `++-- `的运算,`echo$((++a))` 和 `echo$((--a))` 表示先进行 `++--` 的运算,在输出a自身的值。

***记忆方法:变量在前,先输出变量值,变量在后,就是先运算后输出变量的值***

### let

let赋值表达式,【注】let赋值表达式功能等同于`((赋值表达式))`  ,例如 `let i=i+8`

### expr

 **expr(evaluate(求值)expressions(表达式))命令:**

expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr是一个手工命令行计算器。

- `expr 2 + 2`
- `expr 2 - 1`
- `expr 2 * 1`
- `expr 2 \* 1`
- `expr 3 % 2`

> expr$[$a+$b]表达式形式
>
> ```bash
> # expr $[2+3]
> 5
> # expr $[2**3]
> 8
> # echo $[2**3]
> 8
> 2、
> # a=1
> # b=2
> # expr $[$a+$b]
> 3
> expr 将其后的串解释为表达式计算其值,运算符前后需有空格
> ```

### bc

bc是UNXI下的计算器,它也可以用在命令行中,bc支持科学计算,所以这种方法功能非常强大

```bash
# 一般工作中不这么用
[root@Lnmp_01 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1*5
5
1/5
0
5/3
1
10+2
12

# 
$ echo 5+10|bc
15
$ echo 5*20|bc
100
$ echo 10%3|bc
1
$ echo 10.5+3.1|bc
13.6
# 与expr的区别
$ echo `expr 1+1`
1+1
$ echo `expr 1 + 1`
2
$ echo `expr 1 + 1.2`
expr: 参数数目错误

$ echo 1+1|bc
2
$ echo 1 + 1|bc
2
# 保留小数位数
$ echo "scale=2;10.45246/2.2315"|bc
4.68
$ echo "10.45246/2.2315"|bc        
4
$ echo 10.45246/2.2315|bc  
4
# 进制转换
$ echo "obase=2;2"|bc
10
$ echo "obase=10;10"|bc
10
$ echo "obase=8;10"|bc 
12
范例:通过命令输出1+2+3+4..+10=XX的表达式,并计算出结果
$ echo `seq -s "+" 10`=`seq -s '+' 10|bc` 
1+2+3+4+5+6+7+8+9+10=55
$ echo `seq -s "+" 10`=$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55
$ echo `seq -s "+" 10`=`seq -s ' + ' 10|xargs expr` 
1+2+3+4+5+6+7+8+9+10=55
$ echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10
$ echo {1..10}|tr " " "+"|bc
55
```

### $[]

```bash
# echo $[2+3]
5
# echo $[  2  * 3  ]
6
```

## 条件测试

​	



### 测试语句

| 语法                        | 说明                                                  |
| --------------------------- | ----------------------------------------------------- |
| 语法1:`test <测试表达式>`  | 利用test命令进行条,**test后有一个空格**               |
| 语法2:`[ <测试表达式> ]`   | 通过单中括号进行,**单中括号中的内容前后都有一个空格** |
| 语法3:`[[ <测试表达式> ]]` | 通过双中括号进行,**双中括号中的内容前后都有一个空格** |
| 语法4:`((<测试表达式>))`   | 通过双小括号进行,**双小括号中的内容前后无空格**       |

在`[[ ]]`中可以使用通配符进行模式匹配。`&& || > <`等操作符可以应用于`[[ ]]`中,不能应用于`[ ]`中。`[]`中一般用`-a、-o、-gt` 等替代对整数进行关系运算,也可以使用Shell的算数运算符 `(( ))`

### **文件测试操作符**

| 测试操作符           | 说明                                                         |
| -------------------- | ------------------------------------------------------------ |
| -f 文件file          | 若文件存在且为普通文件则真                                   |
| -d 文件 directory    | 若文件存在且为目录文件则真                                   |
| -s 文件 size         | 若文件存在切不为空(文件大小非0)则真                        |
| -e 文件 exist        | 若文件存在则真,要区别-f                                     |
| -r 文件 read         | 若文件存在且可读则真                                         |
| -w 文件write         | 若文件存在且可写则真                                         |
| -x 文件 excute       | 若文件存在且可执行则真                                       |
| -L 文件link          | 若文件存在且为链接文件则真                                   |
| f1 -nt f2 never than | 若文件f1比文件f2新则真                                       |
| f1 -ot f2 older than | 若文件f1比文件f2旧则真                                       |
| f1 -ef f2            | 两个文件具有同样的设备号和i结点号                            |
| -k file              | 文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。 [ -k $file ] 返回 false。 |
| -u file              | 文件是否設置了 SUID 位,如果是,則返回 true。 [ -u $file ] 返回 false。 |
| -x file              | 文件是否可執行,如果是,則返回 true。                        |
| -p file              | 文件是否是有名管道,如果是,則返回 true。     [ -p $file ] 返回 false。 |
| -w file              | 文件是否可寫,如果是,則返回 true。           [ -w $file ] 返回 true。 |
|                      |                                                              |

### **字符串测试操作符**

| 常用字符串测试操作符   | 说明                                      |
| ---------------------- | ----------------------------------------- |
| -z "string"            | 若串长度为0则真,-z可以理解为zero         |
| -n "string"            | 若长度不为0则真,-n可以理解为no zero      |
|                        |                                           |
| "string1"="string2"    | 若串1等于串2则真,可使用“==”代替“=”       |
| "string1" != "string2" | 若串1不等于串2则真。但不能用“!==”代替“!=” |

### 二元比较操作符

| 在[]中使用的比较符 | 在[[ ]]中使用的比较符 | 说明                          |
| ------------------ | --------------------- | ----------------------------- |
| -eq                | ==                    | equal的缩写,相等返回真       |
| -ne                | !=                    | not equal的缩写,不相等返回真 |
| -gt                | >                     | 大于greater than              |
| -ge                | >=                    | 大于等于 greate equal         |
| -lt                | <                     | 小于类似less than             |
| -le                | <=                    | 小于等于less equal            |

### 逻辑操作符

| 在[ ]中使用的比较符 | 在[[ ]]中使用的比较符 | 说明                      |
| ------------------- | --------------------- | ------------------------- |
| -a                  | &&                    | and 与,两端都为真,则真  |
| -o                  | \|\|                  | or 或,两端有一个为真则真 |
| !                   | !                     | not 非,相反则为真        |

## 字体颜色

 颜色范围:30-37

```bash
echo -e "\033[30m 黑字体 test \033[0m"
echo -e "\033[31m 红字体 test \033[0m"
echo -e "\033[32m 绿字体 test \033[0m"
echo -e "\033[33m 黄字体 test \033[0m"
echo -e "\033[34m 蓝字体 test \033[0m"
echo -e "\033[35m 紫字体 test \033[0m"
echo -e "\033[36m 天蓝字 test \033[0m"
echo -e "\033[37m 白色字 test \033[0m"
```

40-47

```bash
echo -e "\033[40;37m 黑底白字 welcome \033[0m"
echo -e "\033[41;37m 红底白字 welcome \033[0m" 
echo -e "\033[42;37m 绿底白字 welcome \033[0m" 
echo -e "\033[43;37m 黄底白字 welcome \033[0m" 
echo -e "\033[44;37m 蓝底白字 welcome \033[0m" 
echo -e "\033[45;37m 紫底白字 welcome \033[0m" 
echo -e "\033[46;37m 天蓝底白字 welcome \033[0m" 
echo -e "\033[47;37m 白底白字 welcome \033[0m" 
echo -e "\033[47;30m 白底黑字 welcome \033[0m" 
```

通过定义变量方式给字体加颜色

```bash
#!/bin/bash
red='\033[31m'
green='\033[32m'
yellow='\033[33m'
blue='\033[34m'
pink='\E[1;35m'
end='\E[0m'

echo -e "${red} ======red======${end}"
echo -e "${yellow} =====yellow=====${end}"
```

## 循环



### 当型循环和直到型循环

```bash
while条件句
语法:
while 条件
do
指令...
done
```

until

```bash
until 条件.
do
指令...
done
```

for循环

```
for varName in 变量取值列表
do
    指令...
done
```

### 读取文件

```bash
1. 
cat.log|while read line
do
done
2.
while read line
do
done<a.log
3)
exec <a.log
while read line
do
done
```

### linux产生随机数的

- 系统环境变量`$RANDAM` 范围 ==0-32767== 	

  - 随机数01-99之间的数字

    ```bash
    $[RANDOM%99+1] # 一个数和一个数取余这个数,这个数一定小于这个数
    ```

- openssl: ` openssl rand -base64 8`

- 通过时间获得随机数(date): `date +%s%N`

- `/dev/random`设备:/dev/random设备,存储着系统当前运行的环境的实时数据。它可以看作是系统某个时候,唯一值数据,因此可以用作随机数元数据。我们可以通过文件读取方式,读得里面数据。我们可以通过文件读取方式,读得里面数据。/dev/urandom这个设备数据与random里面一样。只是,他是非阻塞的随机数发生器,读取操作不会产生阻塞。

- UUID:`cat /proc/sys/kernel/random/uuid`

- `mkpasswd -l 8`

## 数组

Shell 数组用==括号==来表示,元素用=="空格"==符号分割开:`array=(value1 value2 ... valuen)`

- 使用下标来定义数组: 	`array[0]=value0`
- 读取数组:`${array[index]}`
- 数组中的所有元素:`${array[*]}"` 或  `${array[@]}"`
- 数组的长度:` ${#array[*]}` 或  ` ${#array[@]}`

分类:

linux

技术点:

相关文章: