基本语法

脚本开头

指定解析器

1
#!/bin/bash

脚本注释

Bash 只支持单行注释,使用 # 开头的都被当作注释语句

1
2
#整行注释
echo hello world #行尾注释

数据类型

Bash 中基本数据类型只有字符串

1
2
3
4
5
#都是字符串
echo abc
echo 123
#将变量声明为整数
declare

字符串联

Bash 中字符串的串联操作不需要任何操作符,直接将两段数据连接在一起。

1
2
echo 123 456
echo 'abc'"def"

环境变量

系统变量

1
2
3
4
5
${HOME}
${PWD}
${SHELL}
${USER}
set #显示所有变量

特殊变量

1
2
3
4
5
${n} #n 为数字,0 为命令本身,从 1 开始依次往下
${#} #输入参数的个数
${*} #所有参数,看成一个整体
${@} #所有参数,区分对待
${?} #返回最后一次命令执行状态,0 成功,非 0 失败

自定变量

1
2
3
4
5
6
#直接赋值,不要有空格
变量名=值 #unset 撤销,${变量名} 引用
#静态变量
readonly 变量名=值
#全局变量
export 变量名

基本运算

运算符

1
2
3
4
5
6
7
8
9
10
$((运算式))
$[运算式]
#加,减,乘,除,取余,运算符间要有空格
expr +
expr -
expr *
expr /
expr %
&& #逻辑与
|| #逻辑或

条件判断

[ 条件 ],前后都要有空格

判断条件

整数比较

  • =
  • -lt(less than):小于
  • -le(less equal):小于等于
  • -eq(equal):等于
  • -gt(greater than):大于
  • -ge(greater equal):大于等于
  • -ne(Not requal):不等于

    文件权限

  • -r(read):读取
  • -w(write):写入
  • -x(execute):执行

    文件类型

  • -f(file):文件存在且为常规文件
  • -e(existence):文件存在
  • -d(directory):文件存在且为目录

    流程控制

    if

    1
    2
    3
    4
    5
    6
    7
    8
    if [ 条件判断 ]:then
    程序
    fi

    if [ 条件判断 ]
    then
    程序
    fi

    case

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    case $变量名 in
    "值1")
    程序
    ;;
    "值2")
    程序
    ;;
    *)
    程序
    ;;
    esac

    for

    1
    2
    3
    4
    for((初始值;循环条件;变量变化))
    do
    程序
    done
    1
    2
    3
    4
    for 变量 in 值1 值2 值3 ...
    do
    程序
    done

    while

    1
    2
    3
    4
    while [ 条件判断 ]
    do
    程序
    done

    输入

    read(选项)(参数)

    选项

    -p:指定读取值的提示符
    -t:指定读取值的倒计时

    参数

    变量:指定读取值的变量名

    函数

    系统函数

    basename [string / pathname] [suffix]:删除最后一个/的所有前缀,还可以指定删除suffix后缀
    dirname 文件绝对路径:去除文件名,返回剩下的路径

    自定函数

    1
    2
    3
    4
    5
    6
    function 函数名()
    {
    Action;
    &?或者return int(0-255);
    }
    函数名

    工具

    cut

    cut [选项] filename:剪切数据
    -f:列号,提取第几列
    -d:分隔符,按指定分隔符分割列,默认为制表符

    sed

    sed [选项] ‘命令’ filename:按行依次执行,结果打印到屏幕,不改变文件内容,除非重定向存储输出
  • -e
  • -i:直接修改文件
  • a:新增
  • d:删除
  • s:查找并替换
    1
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

    awk

    awk 其实不仅仅是工具软件,还是一种编程语言

    基本用法

    1
    2
    3
    awk [选项] '匹配{} 匹配{} 匹配{}' <filename>
    -F:指定分割符,默认按空格和制表符
    awk -F':' '{print $1}' /etc/passwd

    内置变量

  • $0 表示当前行,然后用 $1、$2、$3 依次表示第一个字段、第二个字段、第三个字段
  • NF 表示当前行有多少个字段,依次用 $NF 表示最后一个字段、$(NF-1) 表示倒数第二个字段
  • NR 表示当前处理的是第几行,如打印序号
    1
    awk -F ':' '{print NR " - " $1}' /etc/passwd
  • FILENAME 表示当前文件名
  • FS 表示字段分隔符,默认是空格和制表符
  • RS 表示行分隔符,用于分割每一行,默认是换行符
  • OFS 表示输出字段的分隔符,用于打印时分隔字段,默认为空格
  • ORS 表示输出记录的分隔符,用于打印时分隔记录,默认为换行符
  • OFMT 表示数字输出的格式,默认为 %.6g

    内置函数

  • toupper():将字符转为大写
    1
    awk -F ':' '{print NR " - " toupper($1)}' /etc/passwd
  • tolower():将字符转为小写
  • length():返回字符串长度
  • substr():返回子字符串
  • sin():正弦
  • cos():余弦
  • sqrt():平方根
  • rand():随机数

    指定条件

    在动作前面指定输出条件,只输出符合条件的行
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #输出奇数行
    awk -F ':' 'NR % 2 == 1 {print $1}' /etc/passwd
    #输出第三行以后的行
    awk -F ':' 'NR >3 {print $1}' /etc/passwd
    #下面的例子输出第一个字段等于指定值的行
    awk -F ':' '$1 == "root" {print $1}' /etc/passwd
    awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' /etc/passwd
    #使用 if 语句编写复杂的条件
    awk -F ':' '{if ($1 > "m") print $1}' /etc/passwd
    awk -F ':' '{if ($1 > "m") print $1; else print "---"}' /etc/passwd

    xargs

    Unix 系统的一个很有用的命令,作用是将标准输入转为命令行参数
    1
    2
    3
    4
    5
    6
    xargs [-选项] [命令]
    -d:默认将换行符和空格作为分隔符,把标准输入分解成命令行参数
    -p:打印出要执行的命令,询问用户是否执行
    -t:打印出最终要执行的命令,直接执行,不需要确认
    #命令默认是 echo
    echo "1 2 3" | xargs mkdir
    find 命令有一个特别的参数 -print0,指定输出的文件列表以 null 分隔;xargs 命令的 -0 参数表示用 null 当作分隔符
    1
    2
    3
    4
    #删除更目录下所有文件
    find / -type f -print0 | xargs -0 rm
    #找出 txt 文件并搜索是否包含 abc 字符
    find . -name "*.txt" | xargs grep "abc"

    sort

    sort(选项)(参数):排序

    知识

    信息操作

    Linux 有三个标准 IO:stdin(标准输出)、stdout(标准输入)、stderr(标准错误),对应的文件描述符是 0、1、2


    Linux 下,当一个用户进程被创建的时候,要从某个地方读入数据、将数据输出到某个地方,因此系统会自动为该进程创建三个数据流(stream)

    2 > &1

    将标准错误重定向到标准输入上,& 是为了区分文件描述符和文件名

    1 > /dev/null

    将标准输出重定向到/dev/null的设备文件,null表示一个空设备文件,用来丢弃信息

    2 > &1 1 > /dev/null

    将标准错误重定向到标准输入,同时标准输出又重定向到/dev/null,也就是输所有信息全部丢弃

    变量操作

    给变量赋值并引用
    1
    2
    3
    4
    a="0"
    b="$a"
    c="${b}"
    echo $a $b $c
    还可以引用未定义、为赋值的变量
    1
    2
    3
    echo $a
    b=
    echo $a $b