Bash脚本编写是Linux和Unix系统管理员、开发人员和高级用户等的一项基本技能。无论您是自动执行重复性任务、创建复杂的工作流程还是管理系统配置,Bash脚本都使您能够充分发挥命令行的潜力。
在本备忘单中,我们将深入探讨Bash脚本的基本概念、语法和最佳实践。从基本命令到高级技术,本指南可为初学者和经验丰富的Bash爱好者提供方便的参考。
通过Bash脚本释放自动化的力量、简化您的工作流程并释放您的生产力。
变量
变量充当构建块,在脚本中实现动态且灵活的行为。无论您是存储数据、操作字符串还是控制程序流,理解Bash变量对于编写健壮且高效的脚本都至关重要。
首先,我们定义一个变量:
name=”John” |
使用变量:
echo $name echo “$name” echo “${name}!” |
代换
Bash 中的字符串替换允许您用另一个字符串替换字符串的一部分:
original_string=”Hello, World!” new_string=”${original_string/Hello/Hi}” echo “$new_string” # Output: Hi, World! |
切片
Bash 中的字符串切片涉及根据字符串的索引提取字符串的一部分。与其他一些编程语言不同,Bash 没有内置对字符串切片的支持,但您可以使用参数扩展和子字符串提取来实现类似的功能:
${string:start:length} |
其中start是起始索引(从 0 开始),length是要提取的字符数。
例子:
echo “${name:0:2}” # “Jo” (slicing) echo “${name::2}” # “Jo” (slicing) echo “${name::-1}” # “Joh” (slicing) echo “${name:(-1)}” # “n” (slicing from right) echo “${name:(-2):1}” # “h” (slicing from right) |
改变大小写
在 Bash 中,您可以使用参数扩展轻松更改字符串的大小写:
echo “${str,}” # lowercase 1st letter echo “${str,,}” # all lowercase echo “${str^}” # uppercase 1st letter echo “${str^^}” # all uppercase |
默认值
在 Bash 脚本中,您可以使用参数扩展为变量分配默认值。当您想要确保变量具有值(即使未显式设置)时,这非常有用。
${foo:-val} # $foo, or val if unset (or null) ${foo:=val} # set $foo to val if unset (or null) ${foo:+val} # val if $foo is set (and not null) ${foo:?message} # show error message and exit if $foo is unset (or null) |
特殊变量
Bash 中的特殊变量是预定义的变量,它们保存特定信息或在 Bash 脚本上下文中具有特殊含义。这些变量由特殊字符或预定义名称表示,并提供有关脚本环境、命令行参数和执行状态的有价值的信息。以下是 Bash 中一些常用的特殊变量:
$? # exit status of last task $! # PID of last background task $ # PID of shell $0 # filename of the shell script $_ # last argument of the previous command |
评论
注释是脚本中被解释器忽略的行,充当阅读代码的注释或解释。它们用于记录特定代码段的用途、提供说明或向脚本添加说明。注释不会被执行,并且不会影响脚本的功能。
在 Bash 脚本中,注释可以通过两种方式编写:
单线:
# Single line comment |
多线:
: ‘ This is a multi line comment ‘ |
循环
Bash 中的循环允许您重复执行一组命令,直到满足指定的条件。 Bash 中的循环主要分为三种类型:
For循环
对列表或范围中的每个项目执行一系列命令。
for VARIABLE in 1 2 3 4 5 .. N do … done |
for循环的例子:
for i in {1..10}; do echo $i; done for i in $(seq 1 10); do echo $i; done |
类C版本:
for ((i = 0 ; i < 100 ; i++)); do echo “$i” done |
While 循环
只要给定条件为真,就执行一系列命令。
while [CONDITION]; do … done |
例子:
逐行读取文件:
while read -r line; do echo “$line” done < file.txt |
无限循环:
while true; do ··· done |
直到循环
执行一系列命令,直到给定条件成立。
until [CONDITION] do … done |
例子:
counter=0 until [ $counter -gt 10] |
这些循环对于自动化重复任务、迭代数据集合以及控制 Bash 脚本中的程序流至关重要。
功能
Bash 函数是执行特定任务的可重用代码块。它们允许您将一系列命令封装到单个实体中,使您的脚本更加模块化、可读且更易于维护。函数可以接受参数、执行命令和返回值。它们对于组织和构建 Bash 脚本以及减少代码重复特别有用。
定义函数
function hello { echo “hello world” } |
替代语法:
hello() { echo “hello world” } |
单行:
function function_name { command; } |
函数参数
函数参数,也称为参数,是调用函数时传递给函数的值。它们提供了一种将数据传递到函数中的方法,以便每次调用函数时都可以对不同的输入进行操作。
$# # number of arguments $1 # first argument $2 # second argument $n # nth argument $* # all positional arguments (as a single word) $@ # all positional arguments (as separate strings) $_ # last argument of the previous command |
状况
条件用于根据表达式的评估或命令的结果做出决策。它们使脚本能够根据条件是真还是假来采取不同的路径或执行不同的代码块。 Bash 条件通常与条件语句一起使用,例如if、elif(else if) 和else。
文件
与文件相关的测试条件用于检查文件和目录的各种属性或属性:
[[ -e FILE ]] # file exists [[ -r FILE ]] # file is readable [[ -h FILE ]] # is symlink [[ -d FILE ]] # is directory [[ -w FILE ]] # file is writable [[ -s FILE ]] # size is > 0 bytes [[ -f FILE ]] # file [[ -x FILE ]] # executable [[ FILE1 -ef FILE2 ]] # same files |
例子:
if [[ -e “file.txt” ]]; then echo “File exists” fi if [ -d “$dirname” ]; then echo “Directory exists” fi if [ -r “$filename” ]; then echo “File is readable” fi if [ -w “$filename” ]; then echo “File is writable” fi if [ -x “$filename” ]; then echo “File is executable” fi if [ ! -s “$filename” ]; then echo “File is empty” fi |
弦乐
与字符串相关的条件用于比较字符串、检查其长度以及根据字符串属性执行各种操作:
[[ -z STRING ]] # empty [[ -n STRING ]] # not empty [[ STRING1 == STRING2 ]] # equal [[ STRING1 != STRING2 ]] # not Equal |
例子:
if [ “$str1” != “$str2” ]; then echo “Strings are not equal” fi if [ “$str1” != “$str2” ]; then echo “Strings are not equal” fi if [[ -z “$string” ]]; then echo “String is empty” else echo “String is not empty” fi if [ -n “$str” ]; then echo “String is not empty” fi if [[ “$str” == *”sub”* ]]; then echo “String contains ‘sub'” fi if [ ${#str} -gt 5 ]; then echo “String length is greater than 5” fi |
数字
Bash 中与数字相关的条件用于执行数值之间的比较:
[[ NUM1 -eq NUM2 ]] # equal [[ NUM1 -ne NUM2 ]] # not equal [[ NUM1 -lt NUM2 ]] # less than [[ NUM1 -le NUM2 ]] # less than or equal [[ NUM1 -gt NUM2 ]] # greater than [[ NUM1 -ge NUM2 ]] # greater than or equal |
例子:
if [[ $n -gt $n2 ]]; then … elif [[ $n -eq $n2 ]]; then … else … fi num1=10 num2=20 if [ “$num1” -eq “$num2” ]; then echo “Numbers are equal” fi num1=10 num2=20 if [ “$num1” -ne “$num2” ]; then echo “Numbers are not equal” fi num1=30 num2=20 if [ “$num1” -gt “$num2” ]; then echo “Number 1 is greater than number 2” fi num1=20 num2=20 if [ “$num1” -le “$num2” ]; then echo “Number 1 is less than or equal to number 2” fi |
逻辑运算符
逻辑运算符用于对表达式进行逻辑运算
[[ ! X ]] # not [[ X && Y ]] # and [[ X || Y ]] # or |
例子:
age=25 if [ “$age” -gt 18 ] && [ “$age” -lt 30 ]; then echo “Age is between 18 and 30″ fi day=”Saturday” if [ “$day” == “Saturday” ] || [ “$day” == “Sunday” ]; then echo “It’s a weekend!” fi is_raining=false if ! $is_raining; then echo “It’s not raining” fi |
案件
该case语句提供了一种根据变量的值执行不同代码块的方法。这与switch其他编程语言中的语句类似。
case “$1” in start) echo “start” ;; stop) echo “stop” ;; *) echo “Usage: $0 {start|stop}” ;; esac #!/bin/bash day=”Sunday” file=”example.txt” |
重定向
重定向用于控制命令的输入和输出。以下是重定向的概述和示例:
./program > output.txt # stdout to file ./program >> output.txt # append stdout to file ./program 2> error.log # stderr to file ./program 2>&1 # stderr to stdout ./program 2>/dev/null # stderr to /dev/null ./program >output.txt 2>&1 # stdout and stderr to file, equivalent to &> ./program &>/dev/null # stdout and stderr to /dev/null ./program < input.txt # stdin from input.txt |
将命令的标准输出重定向到文件或设备:
echo “Hello, World!” > output.txt |
将命令的标准输出附加到文件中:
ps aux >> processes.txt |
从文件重定向命令的标准输入:
grep “keyword” < input.txt |
将标准错误输出重定向到文件或设备:
ls /nonexistent 2> errors.txt ls /nonexistent &> combined_output.txt |
将一个命令的输出重定向为另一命令的输入:
ls -l | grep “file” |
赫里多克
Bash 中的此处文档 (heredoc) 是一种将多行输入传递给命令或脚本的方法。它允许您直接在脚本中指定文本块,而无需转义特殊字符或担心引用问题。
command << delimiter text delimiter |
例子:
cat <<END … END |
Shell命令执行
将命令括在反引号内会执行该命令并替换其输出(过时的语法):
result=`ls -l` echo $result |
与反引号类似,但具有改进的可读性和嵌套功能:
result=$(ls -l) echo $result |
在另一个命令或字符串中内联执行命令:
echo “Current directory $(pwd)” echo “Current directory `pwd`” |
执行存储在字符串变量中的一个命令或一组命令:
command=”ls -l” eval $command |
结论
总之,掌握 Bash 脚本为自动化任务、管理系统配置和提高命令行工作效率打开了一个充满可能性的世界。通过理解变量、循环、函数、条件和本文中介绍的其他基本概念,您可以创建强大的脚本来简化工作流程并有效解决复杂问题。
虽然本文为开始使用 Bash 脚本编写奠定了坚实的基础,但请记住,总是有更多东西需要学习。探索高级主题,尝试不同的技术,并利用大量可用的在线资源,包括论坛、教程和文档。
无论您是系统管理员、开发人员,还是只是希望提高命令行体验的效率,Bash 脚本编写都是您工具包中一项宝贵的技能。通过练习和坚持,您将熟练地编写 Bash 脚本来自动执行任务、简化工作流程并释放 Linux 命令行的全部潜力。