该文整理一些常用的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” ....” ,这是将参数传递给其他程序的最佳方式,因为会保留所有内嵌在每个参数里的任何空白。 |
进程状态变量 | |
$$ |
获得当前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]表达式形式
# expr $[2+3]5# expr $[2**3]8# echo $[2**3]82、# a=1# b=2# expr $[$a+$b]3expr 将其后的串解释为表达式计算其值,运算符前后需有空格
bc
bc是UNXI下的计算器,它也可以用在命令行中,bc支持科学计算,所以这种方法功能非常强大
# 一般工作中不这么用[root@Lnmp_01 ~]# bcbc 1.06.95Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.This is free software with ABSOLUTELY NO WARRANTY.For details type `warranty\'.1*551/505/3110+212#$ echo 5+10|bc15$ echo 5*20|bc100$ echo 10%3|bc1$ echo 10.5+3.1|bc13.6# 与expr的区别$ echo `expr 1+1`1+1$ echo `expr 1 + 1`2$ echo `expr 1 + 1.2`expr: 参数数目错误$ echo 1+1|bc2$ echo 1 + 1|bc2# 保留小数位数$ echo "scale=2;10.45246/2.2315"|bc4.68$ echo "10.45246/2.2315"|bc4$ echo 10.45246/2.2315|bc4# 进制转换$ echo "obase=2;2"|bc10$ echo "obase=10;10"|bc10$ echo "obase=8;10"|bc12范例:通过命令输出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 " " "+"|bc55
$[]
# 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
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
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"
通过定义变量方式给字体加颜色
#!/bin/bashred=\'\\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}"
循环
当型循环和直到型循环
while条件句语法:while 条件do指令...done
until
until 条件.do指令...done
for循环
for varName in 变量取值列表do指令...done
读取文件
1.cat.log|while read linedodone2.while read linedodone<a.log3)exec <a.logwhile read linedodone
linux产生随机数的
-
系统环境变量
$RANDAM
范围 0-32767
随机数01-99之间的数字
$[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[@]}