基本语法

Bash(Bourne Again SHell)是一个广泛使用的shell,尤其是在GNU/Linux系统中。它提供了丰富的功能和语法来执行命令、编写脚本以及进行自动化任务。以下是Bash的一些基本语法和概念:

1. 命令

  • 基本命令执行:直接在终端输入命令并按回车键执行。
ls -l

注释

在 Bash 脚本中,注释是用于提供关于脚本功能的说明或解释代码段如何工作的文本。Bash 脚本中的注释不会被执行,而是被 shell 忽略。

在 Bash 中,有两种方式可以添加注释:

  1. 使用 # 符号: 在行首添加 # 符号可以使该行成为注释。这适用于单行注释。例如:

    # 这是一个单行注释
    echo "这行代码会被执行"
    

    # 符号之后的任何内容都将被视为注释,直到行尾。你也可以将 # 符号放在行的任何位置,但通常我们将其放在行首以保持代码的可读性。

  2. 使用 : 命令: 虽然不常见,但你也可以使用 : 命令(空命令)与 # 符号类似地创建单行注释。但请注意,这不是一个真正的注释,因为 : 是一个有效的 Bash 命令(尽管它什么也不做)。但这种方式在某些上下文中(如 if 语句或 while 循环中)可以创建类似注释的效果。

    : '这是一个使用冒号和单引号的单行注释'
    echo "这行代码会被执行"
    

    但是,通常推荐使用 # 符号进行注释,因为它更清晰且更易于理解。

多行注释: Bash 没有直接的多行注释语法,但你可以通过多次使用 # 符号或者使用 : 命令和 Here Document(这里文档)来模拟多行注释。但更常见的方法是使用多个单行注释,或者使用代码块(如果适用)来包围或“注释掉”多行代码。

例如,你可以使用多个 # 符号来“注释掉”多行代码:

# 以下是注释掉的多行代码
# echo "这行不会被执行"
# echo "这行也不会被执行"

echo "这行代码会被执行"

或者使用 Here Document 和 : 命令来模拟多行注释(尽管这不是推荐的做法,因为它实际上在执行一个命令):

: <<'END'
这是一个模拟的多行注释
它不会执行任何命令
也不会有任何输出
END

echo "这行代码会被执行"

但是,再次强调,通常推荐使用多个单行注释来替代多行注释,因为它更清晰且更符合 Bash 的标准用法。

2. 变量

  • 定义变量:没有专门的命令来定义变量,只需给变量赋值即可。
variable_name="value"
  • 访问变量:使用$前缀和变量名来访问变量的值。
echo $variable_name
  • 特殊变量:如$HOME(用户家目录)、$PATH(命令搜索路径)等。

3. 引号

  • 双引号:允许变量扩展和命令替换。
echo "The value of variable_name is $variable_name"
  • 单引号:不会进行变量扩展或命令替换。
echo 'The value of variable_name is $variable_name'
  • 反引号(或$(...)):用于命令替换,即执行命令并将输出赋给变量或直接在echo等命令中使用。
output=$(ls -l)
echo $output

echo `ls -l`

4. 数组

  • 定义数组:使用括号()来定义数组,并用空格分隔元素。
array_name=(value1 value2 value3)
  • 访问数组元素:使用${array_name[index]}来访问数组中的元素。
echo ${array_name[0]}  # 输出value1

5. 控制结构

  • if 语句:用于条件判断。
if [ condition ]; then
    # do something
elif [ another_condition ]; then
    # do something else
else
    # do something if neither condition is true
fi
  • for 循环:遍历列表或数组。
for variable in list; do
    # do something with $variable
done

for (( i=0; i<10; i++ )); do
    # do something with $i
done
  • while 循环:只要条件为真,就执行循环体。
while [ condition ]; do
    # do something
done
  • case 语句:类似于其他编程语言中的switch语句。
case $variable in
    pattern1)
        # do something
        ;;
    pattern2)
        # do something else
        ;;
    *)
        # default action
        ;;
esac

6. 函数

  • 定义函数:使用function关键字或省略该关键字并直接使用函数名来定义。
function my_function {
    # function body
}

my_function() {
    # function body
}
  • 调用函数:直接输入函数名即可。
my_function

7. 引用和转义

  • 引用:使用引号来引用字符串,如上所述。
  • 转义:使用反斜杠\来转义特殊字符,如\n(换行)、\t(制表符)等。

8. 通配符和正则表达式

  • 通配符:如*(匹配任意字符序列)、?(匹配任意单个字符)等,常用于文件名匹配。
  • 正则表达式:用于模式匹配和文本搜索,如^(行首)、$(行尾)、.(任意单个字符)等。Bash中的正则表达式主要用于grepsedawk等工具中。

9. 管道和重定向

  • 管道:使用|将一个命令的输出作为另一个命令的输入。
ls -l | grep "txt"
  • 重定向:使用>>>将命令的输出重定向到文件,使用<将命令的输入从文件重定向。
ls -l > output.txt  # 将输出重定向到文件
echo "Hello

模式扩展

引号和转义

单引号:

  • 单引号内的所有内容都会被视为纯文本,即不会进行任何形式的解释或替换。
  • 变量、命令替换、特殊字符(如 $、\、反引号 `)等都会被当作普通字符处理。

双引号:

  • 双引号内的内容会被解释,允许变量替换、命令替换等。
  • $\` 等特殊字符会保留其特殊含义。
#!/bin/bash  
  
variable="Hello, World!"  
echo 'This is $variable inside single quotes.'  # 输出:This is $variable inside single quotes.
  
variable="Hello, World!"  
echo "This is $variable inside double quotes."  # 输出:This is Hello, World! inside double quotes.

  
files=$(ls /tmp)  # 使用 $() 执行命令并将输出赋值给变量  
echo "Files in /tmp: $files"  # 输出:Files in /tmp: <列出/tmp目录下的文件>  
  
# 或者直接在双引号内使用命令替换  
echo "Today's date is: $(date)"  # 输出:Today's date is: <当前日期和时间>

echo "This is a dollar sign: \$"  # 输出:This is a dollar sign: $

Bash脚本的基本结构:函数、条件语句、循环语句、变量、数组、文件操作等

退出

在Bash中,使用exit命令可以退出当前脚本的执行,同时exit status可以指定一个退出状态码。 这个status状态码会返回给父进程,以指示脚本的运行结果。status值必须在0-255之间,exit会隐式的返回最后一个命令的返回值,如果命令没有返回值,则返回值为0作为状态码,表示成功。一般情况下,0为成功,1-255为失败。

#!/bin/bash
COMMAND_1
...
COMMAND_LAST
# 将以最后的命令来决定退出状态
exit

exitexit $? 以及省略 exit 效果等同,$? 为上一条命令的退出状态