逻辑判断[ ]
测试命令 | 作用 |
---|---|
[ -d DIR ] | 如果DIR存在并且是⼀一个⽬目录则为真 |
[ -f FILE ] | 如果FILE存在且是⼀一个普通⽂文件则为真 |
[ -z STRING ] | 如果STRING的长度为零则为真 |
[ -n STRING ] | 如果STRING的长度⾮非零则为真 |
[ STRING1 = STRING2 ] | 如果两个字符串相同则为真 |
[ STRING1 != STRING2 ] | 如果字符串不相同则为真 |
- 大小比较
[ ARG1 OP ARG2 ]
: ARG1和ARG2应该是整数或者取值为整数的变量,OP是-eq
(等于)- ne
(不等于)-lt
(小于)-le
(小于等于)-gt
(大于)-ge
(大于等于)之中的一个 - 逻辑与或非
带与、或、⾮非的测试命令
[ ! EXPR ]
: EXPR可以是上表中的任意一种测试条件,!表示逻辑-反
[ EXPR1 -a EXPR2 ]
: EXPR1和EXPR2可以是上表中的任意⼀种测试条件,-a表示逻-与
[ EXPR1 -o EXPR2 ]
:EXPR1和EXPR2可以是上表中的任意一种测试条件,-o表示-或
if/then/elif/else/fi
#!/bin/bash
if [ -d /bin ]; then #开始
echo "/bin is a dir"
fi #结束
if :; then #开始
echo "/ is always true"
fi #结束
:是⼀个特殊的命令,称为空命令,该命令不做任何事,但Exit Status总是真
case/esac
#!/bin/bash
read val
case $val in #开始
a)
echo "enter val is a"
;;
b)
echo "enter val is b"
;;
*)
echo "enter val is *"
;;
esac #结束
循环
for/do/done
1. for i in {1..100}
do
echo "hello world\n"
done
2. for(( i=0; i<100; i++ ))
while/do/done
1. while[$i -le 100]
do
echo "hello world\n"
done
函数(echo与return区别)
函数就像是迷你脚本,调用函数时可以传任意个参数,在函数内同样是用$0、$1、$2
等变量来提取参数,函数中的位置参数相当于函数的局部变量,改变这些变量并不会影响函数外面的$0、$1、$2
等变量。
- 函数中可以用return命令返回,如果return后面跟一个数字则表示函数的Exit Status。
- echo则可以返回任何类型,实际上都当作字符串输出,是一条输出语句
数组
#定义数组
1. arr=""
arr[0]="123"
arr[1]="qwe"
2. arr=("123" "qwe" "asd")#必须有空格隔开
arr1=("123"
"qwe"
"asd")
#读取数组元素值的⼀一般格式是:
1. ${array_name[index]}
#使⽤用@ 或 * 可以获取数组中的所有元素:
1. echo ${arr[*]}
运算符
- 优先级 ! > && > ||
- 逻辑运算符 < 关系运算符
- 逻辑运算符 : ! && || -a -o
- 关系运算符 : < > > \< == = != – eq –ne -gt -ge –lt -le
单引号和双引号
首先,单引号和双引号,都是为了解决中间有空格的问题。
因为空格在Linux中时作为一个很典型的分隔符,比如string1=this is astring
,这样执行就会报错。为了避免这个问题,因此就产生了单引号和双引号。他们的区别在于,单引号将剥夺其中的所有字符的特殊含义,而双引号中的'$'
(参数替换)和'`'
(命令替换)是例外。所以,两者基本上没有什么区别,除非在内容中遇到了参数替换符$和命令替换符。
所以下面的结果:
num=3
echo ‘$num’
$num
echo “$num”
3
所以,如果需要在双引号””里面使用这两种符号,需要用反斜杠转义。
反引号"``"
这个东西的用法,我百度了一下,和$()
是一样的。在执行一条命令时,会先将其中的 "``"
,或者是$()
中的语句当作命令执行一遍,再将结果加入到原命令中重新执行,例如:
cho `ls`
会先执行 ls 得到xx.sh等,再替换原命令为:
echo xx.sh
最后执行结果为
xx.sh
那么,平时我们遇到的把一堆命令的执行结果输出到一个变量中,需要用这个命令替换符括起来,也就可以理解了。
这里又涉及到了一个问题,虽然不少系统工程师在使用替换功能时,喜欢使用反引号将命令括起来。但是根据POSIX规范,要求系统工程师采用的是$(命令)
的形式。所以,我们最好还是遵循这个规范,少用“,多用$()
小括号,中括号,和大括号的区别
那么,下面又涉及到了一个问题,就是小括号,中括号,和大括号的区别。
先说说小括号和大括号的区别。这两者,实际上是“命令群组”的概念,也就是commandgroup。
( ) 把 command group 放在subshell去执行,也叫做 nested sub-shell。
{ } 则是在同一个 shell 內完成,也称为 non-namedcommand group。
所以说,如果在shell里面执行“函数”,需要用到{},实际上也就是一个命令群组么。
不过,根据实测,test=
(ls−a)可以执行,但是test=
{ls–a}语法上面是有错误的。估计也和上面所说的原因有关。
另外,从网上摘录的区别如下:
- ()只是对一串命令重新开一个子shell进行执行
- {}对一串命令在当前shell执行
- ()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开
- ()最后一个命令可以不用分号
- {}最后一个命令要用分号
- {}的第一个命令和左括号之间必须要有一个空格
- ()里的各命令不必和括号有空格
- ()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令
两个括号(()),是代表算数扩展,就是对其包括的东西进行标准的算数计算——注意,不能算浮点数,如果需要算浮点数,需要用bc做。
至于中括号[],感觉作用就是用来比较的。比如放在if语句里面,while语句里面,等等。
这里引出来[..]和[[…]]的区别:(摘自网上,实测证实):使用[[… ]]条件判断结构, 而不是[ … ], 能够防止脚本中的许多逻辑错误.比如,&&, ||, <,和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话,会报错。
[[ ]] 比[ ] 具备的优势
[[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
使用[[ … ]]条件判断结构,而不是[… ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。
bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。使用[[ … ]]条件判断结构, 而不是[ … ], 能够防止脚本中的许多逻辑错误. 比如,&&, ||, <, 和> 操作符能够正常存在于[[]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错。
进度条编写
i=1
str=""
arr=("-" "/" "|" "\\")
for i in {1..100}
do
let j=i%4
printf "[%-100s][%d%%][%c]\r" "$str" "$i" "${arr[j]}"
sleep 0.1
str+="#"
done
echo ""