FreezeJ' Blog

Shell语法整理

2019-05-09

Shell语法有很多技巧和不同的使用方法,本文对常用的一些语法、技巧进行整理,便于查阅。

语法整理

路径操作

  • dirname:获取目录
  • basename:获取文件名
  • realpath:获取完整路径(对于不同系统,不一定有这个命令)

“”和’’与 `` 在shell变量中的区别(双引、单引、反引):

  • 双引:允许通过$符引用其他变量
  • 单引:禁止引用其他变量符,视为普通字符
  • 反引:将命令执行的结果输出给变量

条件测试类型

  • 整数测试
  • 字符测试
  • 文件测试

条件测试的表达式

  • [ expression ] 空格不能省略 命令测试法(一个中括号是bash的命令),有时候不好使。
  • [[ expression ]] 关键字测试法(两个中括号是bash的关键字),推荐使用这种表达式。
  • test expression

整数比较

  • -eq: 测试两个整数是否相等;比如 $A -eq $B
  • -ne: 测试两个整数是否不等;不等,为真;相等,为假; not equal
  • -gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
  • -lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
  • -ge: 大于或等于
  • -le:小于或等于

字符测试

  • ==:测试是否相等,相等为真,不等为假
  • !=: 测试是否不等,不等为真,等为假
  • =~: 测试包含关系,包含为真
  • > (在ASCII码表中的先后顺序,从左至右逐字比较)使用[[,在[中使用不靠谱
  • <
  • -n string: 测试指定字符串是否为空,空则真,不空则假
  • -z string: 测试指定字符串是否不空,不空为真,空则为假

文件测试

  • -e FILE:测试文件是否存在
  • -f FILE: 测试文件是否为普通文件
  • -d FILE: 测试指定路径是否为目录
  • -r FILE: 测试当前用户对指定文件是否有读取权限;
  • -w 是否可写
  • -x 是否可执行
[ -e /etc/inittab ]  # 判断/etc/inittab是否存在
[ -x /etc/rc.d/rc.sysinit ]    # 判断/etc/rc.d/rc.sysinit是否有执行权限
[ ! -e /etc/inittab ] # 取反

组合调试条件

  • -a:与
  • -o:或
  • !:非

如:
if [ $# -gt 1 -a $# -le 3 ] # 参数个数大于1小于等于3
或者
if [ $# -gt 1 ] && [ $# -le 3 ]


命令的间逻辑关系:短路与或
短路与: &&

  • 第一个条件为假时,第二条件不用再判断,最终结果已经有;
  • 第一个条件为真时,第二条件必须得判断;

短路或: ||

  1. 逻辑是从左到右全部判断
  2. 短路是能判断结果就停止

算术运算

A=3
B=6
  1. let算术运算表达式 let C=$A+$B
  2. $[算术运算表达式]C=$[$A+$B]
  3. $((算术运算表达式))C=$(($A+$B))
  4. expr算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用C=`expr \$A + \$B\

圆整:丢弃小数点后的内容,不是四舍五入

bash变量的类型

  • 本地变量(局部变量)
  • 环境变量
  • 位置变量:
    $0:脚本名
    $1, $2, ...
    shift踢掉第一个参数,第二个变成第一个,第三个变成第二个,以此类推
    shift x表示踢掉几个
  • 特殊变量:
    $?:退出状态码
    $#:参数的个数
    $*:参数列表(如果使用引号括起来,对于$*来说,参数会合并到一起形成一份数据)
    $@:参数列表

if判断语句

if condition; then
    statements
elif condition; then
    statements
else
    statements
fi

case判断语句

case $var in
      pattern1)       
          command
          ;;
      pattern2)
          command
          ;;            
      *)
          command
          ;;
esac 
# 每个分支使用两个分号结束,结尾以esac结束

循环语句

while循环和for循环属于“当型循环”,而until属于“直到型循环”。

# for循环
a=(a b c d e f)  # a为一个数组
for x in $a; do
    echo $x
done

for x in {1..9};do
  echo $x
done

for x in `seq 10`; do 
  echo $x; 
done

# 创建选择菜单,无限循环
select a in 1 2 3 4 5 6 7; do 
  echo you choice $a
done

# while循环
while true; do
    语句
done

# until循环
i=0  
until [[ "$i" -gt 5 ]]    #直到大于5  
do  
    let "square=i*i"  
    echo "$i * $i = $square"  
    let "i++"  
done

文件操作

f=/home/config.ini
while read -r b; do echo $b+'dada'; done < "$f" #一行一行读取文件
while read b; do echo $b+'dada'; done < $f
while read b; do echo "your input is $b"; done #读入键入的内容
cat 1.txt |while read line; do echo $line; done #读取文件
for x in `cat 1.txt`; do echo $x; done #按空格和回车读取文件

yes | rm -i * # 自动回答y或者其他  比如yes good,自动回答good

函数

# 定义一个函数的两种方式:
function FUNCNAME {
  command
}

FUNCNAME() {
  command
}

# 调用方式:
FUNCNAME

# 自定义执行状态返回值:
return x # x的范围为0-255

# 接受参数的函数:
./a.sh m n 
$1: m
$2: n
$#: 2

字符串操作

参考https://www.cnblogs.com/gaochsh/p/6901809.html

设置默认值:

# 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值
${var:=DEFAULT}

字符串长度:

`sh
num=”12345678”
echo $

Tags: Linux