欢迎来到这个 Bash 基础训练指南!
从这个 Bash 基础训练课程,我们将学习 Bash 的基础知识,并能开始些我们自己的 Bash 脚本和自动化日常任务。
Bash 是一种Unix shell和命令语言。它可以在各种操作系统上广泛使用,而且它也是大多数Linux系统上的默认命令解释器。
Bash 是 Bourne-Again SHell 的简称。
与其他shell一样,我们可以在终端中交互式地直接使用 bash ,还可以像其他编程语言一样使用 bash 来编写脚本。
为了编写 Bash 脚本,我们只需要一个 UNIX 终端和一个文本编辑器(如 Sublime text 、VS Code )或基于终端的编辑器(如 vim 或 nano )。
Bash 文件以 .sh
后缀为扩展名,我们通过创建一个 test.sh
文件为例。
创建文件,我们可以使用 touch
命令:
touch test.sh
或者也可以使用终端自带的编辑器:
vim test.sh
为了使用 bash shell 解释器执行/运行 bash 脚本文件,脚本文件的第一行必须指明到bash可执行文件的绝对路径:
#!/bin/bash
这也被称为 Shebang
。shebang所做的一切就是指示操作系统使用 /bin/bash
可执行文件来运行脚本。
在创建了 test.sh 文件并在第一行指定了 bash shebang 之后,就可以开始创建第一个 Hello World bash脚本了。
为此,再次打开 test.sh 文件,并在 #!/bin/bash
所在行之后添加如下代码:
echo "Hello World!"
然后,保存并退出。
之后,通过运行以下命令使脚本成为可执行文件:
chmod +x test.sh
再来就可以执行文件:
./test.sh
你会在屏幕上看到一个“Hello Wolrd!”的消息。
运行脚本的另一种方式是:
bash test.sh
由于 bash 可以交互使用,所以直接运行以下的命令行和我们使用上面所操作的结果是一样的:
echo "Hello World!"
当我们必须将多个命令组合在一起时,将脚本组合在一起就非常有用。
和其他编程一样,Bash也有变量。但是,变量在 bash 中不是数据类型,变量在 bash 中可以是容器编号和字符。
给变量赋值,使用 =
号赋值:
name=lemonhuang
注意:重要的一点是,
=
符号前后不能有空格。
访问变量,必须使用 $
符号,如下使用 name
变量一样:
echo $name
将变量名包装在花括号中不是必需的,但这被认为是一种很好的做法:
echo ${name}
以上将输出: lemonhuang
,因为这是我们给变量 name
赋的值。
接下来,我们修改以下 test.sh
脚本并引入一个变量。
再次用你习惯打开文件的方式打开脚本文件:
vim test.sh
并且,将文件做如下修改
#!/bin/bash
name="lemonhuang"
echo "Hi my name is $name"
保存,退出并运行脚本:
./test.sh
我们将在屏幕上看到以下输出:
Hi my name is lemonhuang
以下是该脚本的纲要:
#!/bin/bash
- 首先指定我们的shebangname=lemohuang
- 然后声明一个叫 name
的变量并给它赋值echo "Hi my name is $name"
- 最终,通过使用 echo
输出包含变量值的文本内容。在前面的脚本中,我们定义了一个变量,并使用 echo $name
在屏幕上输出该变量的值。
我们接着往下,这次接受用户的输入请求。修改 test.sh
脚本如下:
#!/bin/bash
echo "What is your name?"
read name
echo "Hi there $name"
echo "Welcome!"
上面的代码将提示用户输入,然后将用户输入的作为字符串/文本存储在变量中。 然后,我们可以使用该变量并向它们返回一条消息。
以上脚本的输出过程为:
./test.sh
What is your name?
lemonhuang
Hi there lemonhuang
Welcome!
为了减少代码,我们可以用 read -p
修改第一个 echo
语句,带有 -p
标志的 read
命令会在提示用户输入之前打印一条消息:
#!/bin/bash
read -p "What is your name? " name
echo "Hi there $name"
echo "Welcome!"
与任何其他编程语言一样,我们可以向脚本添加注释。注释用于在代码中给自己留下注释。
要在bash中做到这一点,您需要在该行的开头添加 #
符号。注释永远不会呈现在屏幕上。
下面是一个评论的例子:
# 这是一行注释,注释不会显示屏幕上
让我们继续向脚本添加一些注释:
#!/bin/bash
# Ask the user for their name
read -p "What is your name? " name
# Greet the user
echo "Hi there $name"
echo "Welcome!"
我们可以在执行shell脚本时将参数传递给它。要传递一个参数,只需要将它写在脚本名称之后。例如:
./test.sh 参数
在脚本中,我们可以使用 $1
来引用我们指定的第一个参数。
以此类推,如果我们传递第二个参数,它将以 $2
的形式引用。
下面,我们创建一个名为 arguments.sh
的脚本作为例子:
#!/bin/bash
echo "Argument one is $1"
echo "Argument two is $2"
echo "Argument three is $3"
保存文件,使其可执行:
chmod +x arguments.sh
然后运行文件并传递3个参数:
./arguments.sh dog cat bird
得到的输入如下:
Argument one is dog
Argument two is cat
Argument three is bird
要引用所有参数,可以使用 $@
:
#!/bin/bash
echo "All arguments: $@"
如果你再次运行脚本:
./arguments.sh dog cat bird
将得到以下输出:
All arguments: dog cat bird
需要记住的另一件事是,$0
用于引用脚本本身。
如果需要的话,这是创建自销毁文件的好方法,或者只是获得脚本的名称。
例如,让我们创建一个脚本,它打印出文件的名称,然后删除后面的文件:
#!/bin/bash
echo "The name of the file is: $0 and it is going to be self-deleted"
rm -f $0
如果你曾经做过任何编程,你可能已经熟悉数组。但为了防止你不是开发人员,与变量不同,数组可以在一个名称下保存多个值。
可以通过将值赋值给由空格分隔并包含在()中来初始化数组
。例子:
my_array=("value 1" "value 2" "value 3" "value 4")
要访问数组中的元素,需要通过它们的数字索引来引用它们。
注意:请记住需要使用
花括号
。
value 2
:echo ${my_array[1]}
value 4
:echo ${my_array[-1]}
4
:echo ${my_array[@]}
在计算机科学中,条件语句、条件表达式和条件结构是程序设计语言的特征,它们根据程序设计人员指定的布尔条件的值为真或假来执行不同的计算或操作。
在bash中,[[
复合命令和 [
内置命令使用条件表达式来测试文件属性并执行字符串和算术比较。
下面是最流行的bash条件表达式列表,您不必费力地记住它们,您可以简单地将此页面标记为书签,并在需要时返回到此列表!
[[ -a ${file} ]]
[[ -b ${file} ]]
[[ -c ${file} ]]
[[ -d ${file} ]]
[[ -e ${file} ]]
[[ -f ${file} ]]
[[ -h ${file} ]]
[[ -r ${file} ]]
[[ -s ${file} ]]
[[ -w ${file} ]]
[[ -x ${file} ]]
[[ -L ${file} ]]
varname
(已经分配了一个值),则为真:[[ -v ${varname} ]]
[[ -z ${string} ]]
[[ -n ${string} ]]
=
应该与POSIX一致性的测试命令一起使用。当与 [[
命令一起使用时,它将执行上面描述的模式匹配(复合命令):[[ ${string1} == ${string2} ]]
[[ ${string1} != ${string2} ]]
[[ ${string1} < ${string2} ]]
[[ ${string1} > ${string2} ]]
[[ ${arg1} -eq ${arg2} ]]
[[ ${arg1} -ne ${arg2} ]]
[[ ${arg1} -lt ${arg2} ]]
[[ ${arg1} -le ${arg2} ]]
[[ ${arg1} -gt ${arg2} ]]
[[ ${arg1} -ge ${arg2} ]]
注意:arg1和arg2可以是正整数或负整数
与其他编程语言一样,我们也可以使用 AND
、&
、|
、OR
条件:
[[ test_case_1 ]] && [[ test_case_2 ]] # And
[[ test_case_1 ]] || [[ test_case_2 ]] # Or
在上一节中,我们介绍了一些最流行的条件表达式,现在我们可以将它们与标准的条件语句一起使用,比如if
和if-else
语句。
bash中if语句的格式如下:
if [[ some_test ]]
then
<commands>
fi
然后,我们可以将它与上一节中的条件表达式组合在一起使用,如下示例所示:
#!/bin/bash
# Bash if statement example
read -p "What is your name? " name
if [[ -z ${name} ]]
then
echo "Please enter you name!"
else
echo "Hi there $name"
fi
我们可以将上面的if语句与前面章节中的所有条件表达式一起使用!
#!/bin/bash
admin="lemonhuang"
read -p "What is your username? " username
#Check if the username provided is the admin
if [[ "${username}" == "${admin}" ]] ; then
echo "You are the admin user!"
else
echo "You are NOT the admin user!"
fi
与任何其他语言一样,循环非常有用。在bash中,您可以使用for
循环、while
循环和until
循环。
如下是for
循环语句的结构:
for var in ${list}
do
your_commands
done
例子:
#!/bin/bash
users="john, tony, tom"
for user in ${users}
do
echo "${user}"
done
我们也可以使用for
来处理一系列的数字,例如这里是一种从1到10的循环方法:
#!/bin/bash
for num {1..10}
do
echo ${num}
done
while
循环的结构与for
循环非常相似:
while [ your_condition ]
do
your_commands
done
例子:
#!/bin/bash
counter=1
while [[ $counter -le 10 ]]
do
echo $counter
((counter++))
done
我们来创建一个脚本,请求用户提供他们的名字,并且不允许空的输入:
#!/bin/bash
read -p "What is your name? " name
while [[ -z ${name} ]]
do
echo "Your name can not be blank, please enter a valid name!"
read -p "Enter your name again? " name
done
echo "Hi there ${name}"
现在,如果我们运行上面的操作,并且只按enter而不提供输入,那么循环将再次运行并一次又一次地询问我们的姓名,直到我们真正提供输入为止。
until
和while
循环之间的区别在于,until 循环将在循环中先运行循环体,直到条件为真为止。
结构如下:
until [ your_condition ]
do
your_commands
done
例子:
#!/bin/bash
count=1
until [ $count -gt 10 ]
do
echo $count
((count++))
done
与其他语言一样,我们也可以在bash脚本中使用continue
和break
:
continue
告诉bash脚本停止循环的当前迭代并开始下一个迭代break
告诉bash脚本立即结束循环函数是重用代码的好方法。bash中的函数结构与大多数语言非常相似:
function function_name() {
your_commands
}
在开头省略function关键字,这也是可以的:
function_name() {
your_commands
}
但为了可读性,最好还是加上function
关键词。
举一个“Hello World!”函数的例子:
#!/bin/bash
function hello(){
echo "Hello World Function!"
}
hello
注意:当调用这个函数时,我们不应该添加括号。
向函数传递参数的工作方式与向脚本传递参数的方式相同:
#!/bin/bash
function hello(){
echo "Hello $1!"
}
hello lemonhuang
为了调试bash脚本,可以在执行脚本时使用-x
:
bash -x ./your_script.sh
或者也可以在要调试的特定行之前添加set -x
, set -x
是 启用shell的一种模式,在这种模式下,所有执行的命令都将打印到终端。
另一种测试脚本的方法是使用这个神奇的工具:
https://www.shellcheck.net/
只要复制并粘贴脚本到文本框,工具会给我们一些建议,可以用来改进我们的脚本。
我们也可以在终端直接运行这个工具,参考:
https://github.com/koalaman/shellcheck
到这里,我们就算完成了Bash基础的知识。
为了以后需要引用任何Bash知识时,请务必将此指南添加到你的书签中。
在本教程中,我们只介绍了基础知识,但是我们需要有足够的资源来开始编写一些厉害的脚本和自动化日常任务!
作为下一步,应该尝试编写自己的脚本,并且分享出来! 这是学习任何新的编程或脚本语言的最好方法!