10 分钟内学习 Bash 脚本🧙♂️🪄
介绍
作为一名程序员,学习 Bash 脚本非常重要。它使我们能够编写脚本来自动执行枯燥重复的任务。
脚本的应用和用途非常广泛。从管理系统进程到执行复杂的数据操作,bash 脚本都能帮助我们高效地完成所有工作。
在接下来的 10 分钟内(是的,只有 10 分钟!),我将通过示例介绍 bash 脚本的基础知识,以帮助您简化工作流程。
听起来很有趣?
那么,拿起你最喜欢的饮料,让我们开始编写脚本吧!
先决条件
在我们深入探讨之前,您需要做以下准备:
-
Linux 或 macOS 系统(Windows 用户可以使用 WSL)
-
任何文本编辑器(我们在这里使用 Vim)
-
好奇心和愿意尝试
就是这样! : )
基础知识
在本节中,我们将了解 Bash 脚本的基本命令。这些命令我们会在大多数地方用到,而且它们非常容易理解,所以只需看一下它们,你就可以开始了!
首先,让我们创建一个新的文件夹(也称为目录),用于保存文件。为此,我们使用 mkdir 命令,即“创建目录”。使用方法如下:
mkdir <directory name>
此命令将在您当前位置创建一个新的文件夹/目录。
现在,我们有了目录,让我们进入它。要进入目录,我们将使用 cd 命令,它代表“更改目录”:
cd <directory name>
正如我们在上图中所看到的,我们位于目录“Arindam”内
但是如果你想回到之前的位置怎么办?
没问题!
使用cd ..
返回父目录:
cd ..
现在,如果我们想查看当前目录中的文件和文件夹,我们使用 ls 命令:
ls
这将列出当前目录中的所有文件和文件夹:
让我们创建一个新文件。我们可以使用 touch 命令来完成:
# syntax: touch <filename>
touch my_first_file.txt
这将在我们当前文件夹中创建一个名为“my_first_file.txt”的空文件。
有时,我们可能会忘记我们在哪个目录中工作。
不用担心!
要获取当前工作目录,我们可以使用pwd
代表“打印工作目录”的命令:
pwd
这将显示您当前位置的完整路径。
最后,让我们在屏幕上打印一些内容。我们使用echo
以下命令:
echo "Hello World"
这将在你的终端中显示“Hello, Bash World!”:
这样,我们就学习了 Bash 脚本的基础知识!
很简单吧?
事情会变得更加简单,因为我们会在后续部分继续使用这些。
编写第一个 Bash 脚本
作为开发人员,我们主要使用 VS Code 或其他文本编辑器来编写代码。但对于编写 Bash 脚本,我们更倾向于使用基于终端的编辑器,例如 vim、neovim。
对于本指南,我将使用 vim。
注意:如果你第一次退出 vim 时遇到困难,别担心。我们都经历过 : )
# Command: vim <file name>
vim hello.txt
这将创建一个hello.txt
文件并用 vim 打开。你将看到以下界面:
但是等等!我们这里什么都写不了!!
为什么?
原因很简单,vim 默认以只读模式打开文件。要想在文件上写入,只需按“i”键,它就会进入插入模式,这样我们就可以在文件上写入了:
现在,如何保存这个文件?
这很简单!
首先,我们按下退出插入模式,esc
然后我们只需按下:w
这将更新更改并保存:
现在我们必须摆脱让许多初学者苦苦挣扎的 vim。
嗯,现在不再是这样了。
要退出 vim 编辑器,只需写入:q
,我们就会退出 vim 编辑器。
专业提示:您可以组合使用这些命令来
:wq
一次性保存并退出。
此外,如果我们想打印文件的内容,我们将使用
# command: cat <file name>
cat hello.txt
我们将获得刚刚创建的文件 hello.txt 的内容
现在,让我们创建我们的第一个 bash 脚本。
创建文件firstCommand.sh并用vim打开
vim firstCommand.sh
在这个文件中,我们添加以下内容:
并使用以下方式保存此文件:wq
#!/bin/bash
是告诉 shell 脚本使用哪个解释器的方法。
现在,我们将开始我们的第一个 shell 脚本。
bash firstCommand.sh
我们将得到以下信息:
但是如果我们尝试执行该文件,我们将收到权限被拒绝的错误。
在 Linux 中,我们需要授予文件权限才能作为可执行文件。我们将使用以下命令授予权限:
chmod +x firstCommand.sh
这将使文件 firstCommand.sh 可执行。现在,如果我们执行该文件,我们将得到:
现在一切正常!这样我们就创建了第一个 Bash 脚本!
变量
在 Bash 中我们也可以使用变量。
假设我们要将某些内容从一个位置复制到另一个位置。一般方法是:
cp my/location/path/from my/location/path/to
现在,如果我们使用变量,它将是:
LOC=my/location/path
cp $LOC/from $LOC/to
这更具可读性,不是吗?
另外还有额外好处:如果您以后需要更改路径,则只需在一个地方更改即可!
位置参数
现在,我们将学习位置参数,顾名思义,它从特定位置获取参数。
我们将脚本后面的参数写为参数,并根据它们的位置访问它们。
让我们通过一个例子来理解这一点,我们将创建一个新的脚本,它将接受两个位置参数并打印它们。
使用以下命令创建一个新文件:
vim PosArg.sh
并添加如下代码。
仔细看,这里我们采用位置参数$1
和$2
接下来,保存并使其可执行(正如我们在前面的部分中所做的那样)。
之后,让我们使用两个参数运行可执行文件!
我们得到了预期的结果。这就是我们在 Bash 脚本中使用位置参数的方法。
管道
bash 最常用的功能之一是管道,它使得对另一个命令的输出执行特定操作变得非常容易。
例如,命令的输出很长,您想要过滤它。
我们可以使用管道在一个命令中执行相同的操作,而不是复制该输出并粘贴到另一个命令中。
让我们了解管道的工作原理!
我们将使用以下命令以长格式列出 bin 目录的内容:
ls -l /usr/bin
我们将获得大量文件。请参见下面的屏幕截图。
如您所见,输出非常长,我们不能直接复制该输出进行管道传输。
在这里,我们将使用管道从输出中仅过滤 bash 文件。让我们将命令更新如下:
ls -l /usr/bin | grep bash
grep 用于在文件/文件夹中搜索特定模式。
现在它将仅显示 bash 文件:
这就是它如何简化
输入/输出重定向
好了,让我们来探索 Bash 中输入/输出重定向的奇妙世界。学会之后,你就能像变魔术一样,控制计算机发送信息的方向了!
通过输入重定向,我们可以从文件而不是键盘获取输入。
例如,如果我们想从文件中过滤某个单词,我们可以通过输入重定向轻松实现。我们将文件作为输入传递。
grep "example" < input.txt
这将为我们提供单词 example 在input.txt
如果我们想为命令提供多行输入,我们可以使用<<
。当我们写<<
操作符时,我们会立即在其后跟一个单词,该单词将打开和关闭我们要输入的文本。
很多人会用 EOF 来表示开始和结束,但这不是强制性的,你可以使用任何你想要的格式。在本例中,为了简单起见,我们将使用 EOF。
cat << EOF
> Hey Everyone
> Hope your'e liking this guide
> if so, feel free to share your thoughts
> Thanks
> EOF
现在,我们将在终端中看到 EOF 之间写入的文本:
现在,让我们翻转脚本,讨论一下输出重定向。这才是真正有趣的地方!
输出重定向允许我们将命令输出发送到文件而不是终端。例如,如果我们想将echo "hello world"
命令的输出放入文件hello.txt
,请运行以下命令。
echo "hello world" > hello.txt
> 符号就像一个漏斗,它将输出直接放入文件中,而不是在终端上打印出来。
现在让我们查看hello.txt
文件。为此,运行
cat hello.txt
我们将看到以下内容:
类似地,我们尝试向 中添加另一个输出hello.txt
。运行以下命令:
echo "Hello Arindam, How are you?" > hello.txt
现在,如果我们查看的内容hello.txt
,我们将看到它已经覆盖了文件:
因此,如果我们需要将输出附加到文件,我们需要使用>>
而不是>
让我们尝试将输出附加hello.txt
到>>
:
echo "Follow me on Twitter: @Arindam_1729" >> hello.txt
现在,我们将看到文本附加到 hello.txt 的先前文本中
如果您想将输出记录在文件中,这将非常有用。同时还可以保留您的错误。
If/else 语句
就像其他编程语言一样,我们也可以在 Bash 中编写 if else 语句。
它的语法是:
if (condition);then
statement
elif(condition);then
statement
else
statement
fi
让我们尝试用一个例子来说明
我们将创建一个脚本来获取用户的名字,如果用户名是 Arindam,那么它将打印 Welcome Admin,否则,它将打印“您不是管理员,请以管理员身份登录”。
#!/bin/bash
if [[ "${1,,}" = "arindam" ]]; then
echo "Hey Admin, Welcome to our Bash Tutorial."
elif [[ "${1,,}" = "magician" ]]; then
echo "Hey Magician, You don't have Admin Access"
else
echo "You Don't have Admin access, login as an Admin"
fi
现在让我们尝试用不同的参数来运行它:
案例陈述
If/else 语句适合检查小条件。但随着条件数量的增加,管理起来会变得困难。在这种情况下,我们可以使用 Case 语句
case EXPRESSION in
PATTERN_1)
STATEMENTS
;;
PATTERN_2)
STATEMENTS
;;
PATTERN_N)
STATEMENTS
;;
*)
STATEMENTS
;;
esac
让我们通过一个例子来理解这一点,我们将用 case 语句实现前面的例子。
因此,代码如下:
#!/bin/bash
case ${1,,} in
"arindam")
echo "Hey Admin, Welcome to our Bash Tutorial."
;;
"magician")
echo "Hey Magician, You don't have Admin Access"
;;
*)
echo "You Don't have Admin access, login as an Admin"
;;
esac
现在,让我们执行代码并查看结果:
完美运行。这里还添加了一个结构,使代码更易于阅读。
数组
我们可以为列表中收集的变量分配多个值。我们将这些变量称为数组。
让我们创建第一个数组:
FIRST_ARRAY=(one two three four five six)
现在我们要打印这个数组。为此,我们先尝试打印变量(通常我们会这样做):
echo $FIRST_ARRAY
但是,正如你所见,我们只获取了数组的第一个元素。为了打印整个数组,我们需要这样写
echo ${FIRST_ARRAY[@]}
现在我们可以获取数组的所有元素:
我们还可以根据索引打印单个元素。语法如下:
# Replace INDEX_OF_THE ELEMENT with the index of the element that you want to print
echo ${FIRST_ARRAY[INDEX_OF_THE ELEMENT]}
For 循环
For 循环是 Bash 脚本的基本组成部分。它使我们能够自动执行重复性任务,高效地处理多个项目。其语法如下:
#!/bin/bash
for n in a b c;
do
echo $n
done
现在,让我们尝试使用 for 循环打印我们之前创建的数组的项目。
for item in ${FIRST_ARRAY[@]};
do
echo $item;
done
此循环遍历 FIRST_ARRAY 的每个元素。[@] 符号是参数扩展,表示指向数组的所有元素。与 ${...} 一起使用时,它会扩展为数组元素的完整列表
如果我们执行这个我们将得到:
如果您想删除新行,只需添加
-n
echo 命令。
功能
在某些情况下,我们有很多代码需要多次调用。这时函数就派上用场了。它们就像一小段代码片段,你可以在需要的时候随时调用。
在 Bash 脚本中,函数是组织和重用代码的强大工具。它本质上是一组可以多次调用的命令。
它的语法如下:
function_name () {
commands
}
这些函数是脚本中的小程序,我们可以在脚本中运行它们。这样,我们的代码就可以复用。
现在让我们创建我们的第一个函数。
vim bashfn.sh
并添加以下脚本:
#!/bin/bash
first_fn () {
echo 'This is my first Bash function'
}
first_fn
现在,如果我们运行这个脚本,我们将得到:
我们还可以将参数传递给 bash 函数。要将参数传递给函数,我们必须在函数调用后添加参数。
让我们在脚本中创建一个新函数并向其传递一个参数。
#!/bin/bash
first_fn () {
echo 'This is my first Bash function'
}
first_arg(){
echo "this is the first argument: $1"
}
first_fn
first_arg Arindam
现在如果我们运行这个脚本,我们将得到:
AWK
AWK 是 Bash 中最实用的工具之一。我们使用 AWK 来过滤文件内容或命令输出,以便以我们喜欢的方式获取输出的必要部分。
基本语法是:
# This will print the whole content of the file
awk '{ print }' /path/to/file
让我们通过一个例子来理解这一点,我们将从文本文件中过滤一个单词并打印出来。
首先,让我们创建一个文本文件temp.txt
并添加文本。我们将使用输出重定向来创建它:
echo Arindam Magician Mohun Bagan Barcelona > temp.txt
现在,我们将使用 awk 从文本文件中过滤文本temp.txt
:
如果我们想打印特定的文本,比如第一个/第二个单词,那么我们可以使用$1
和$2
如果我们想打印文件的全部内容,我们将保留打印语句{print }
注意:默认情况下,awk 使用空格字符作为分隔符
结果如下:
我们可以使用不同的字符作为分隔符,而不是默认的分隔符。
让我们创建一个 CSV 文件并了解这一点:
echo Arindam,Magician,Mohun Bagan,Barcelona > temp.csv
这里我们将使用“,”来代替 awk 的默认分隔符
为此,命令将是:
awk -F, {print $3} temp.csv
现在,我们将得到第三个元素:
如果仔细观察,就会发现第三个单词之间有一个空格分隔,但我们没有考虑到这一点,因为我们已经提到过“,”作为分隔符。
我们还可以使用管道和 awk 命令。
echo "hello Arindam" | awk '{print $2}'
如果我们运行这个程序,我们会得到:
统一经济委员会
有时我们想要更改文本文件中的某个值,这时 sed 就非常有用。
SED 是一个命令行工具,它允许我们使用正则表达式修改文本文件中的某些值。
语法如下:
sed 's/text_to_change/to_this_text/g' filename
让我们创建一个testsed.txt
包含一些虚拟文本的文件:
现在,从该文本中,我们将用 Arindam 替换 Messi 的话。为此,命令将是:
sed 's/messi/arindam/g' testsed.txt
运行此命令后我们将得到:
结论
在本文中,我们介绍了基本概念,从基本命令语法到更高级的主题(如函数)。
希望本文对您有所帮助。如果觉得有用,欢迎分享给您的开发者朋友!
另外,关注我以获取更多类似内容:
如需付费合作,请发送电子邮件至:arindammajumder2020@gmail.com。
感谢您阅读到最后。
