简介
Shell 脚本是一种用于自动化操作系统任务的强大工具。它允许你使用命令行接口命令来编写程序。Shell 脚本通常用于日常任务的自动化,如文件管理、程序运行、文本处理等。下面我将介绍一些基础的 Shell 脚本编写方法和语法。
1. 创建 Shell 脚本
要编写 Shell 脚本,首先需要创建一个文本文件,然后在文件的第一行指定解释器,通常是 Bash。例如:
#!/bin/bash
这一行称为“shebang”,它告诉系统这个脚本应该用 /bin/bash
来执行。
2. 赋予执行权限
创建脚本文件后,需要给这个文件赋予执行权限:
chmod +x script_name.sh
3. 基本语法
变量
在 Shell 脚本中定义变量时,不需要类型声明。赋值时等号两侧不能有空格:
name="World"
echo "Hello, $name!"
条件语句
Shell 脚本中的条件语句语法如下:
if [ condition ]; then
# commands
elif [ other_condition ]; then
# other commands
else
# alternative commands
fi
条件测试可以包括文件属性检查、数值比较和字符串比较等。
循环
for 循环:
for i in {1..5}; do
echo "Number $i"
done
while 循环:
count=1
while [ $count -le 5 ]; do
echo "Count $count"
count=$((count + 1))
done
函数
函数在 Shell 脚本中定义如下:
function say_hello() {
echo "Hello, $1!"
}
# 调用函数
say_hello "Alice"
4. 输入和输出
可以使用 read
命令从标准输入中读取数据:
echo "What is your name?"
read name
echo "Hello, $name!"
5. 传递参数
脚本可以接受来自命令行的参数。这些参数内置在特殊变量 $1
, $2
, $3
, …, $N
中:
#!/bin/bash
echo "Running script $0"
echo "First parameter: $1"
echo "Second parameter: $2"
运行 ./script_name.sh Alice Bob
将输出 Alice 和 Bob 作为参数。
6. 特殊字符
#
用于添加注释$
用于访问变量的值;
允许你在同一行写多条命令&&
和||
分别代表 AND 和 OR 操作,用于连接多个命令
7. 错误处理
使用 set
命令来处理脚本中的错误:
set -e # 脚本中的命令如果失败,脚本立即退出
set -u # 引用未设置的变量将被视为错误
8. 数组
在 Bash 脚本中使用数组来存储多个值。数组的声明和使用如下:
# 声明数组
numbers=(1 2 3 4 5)
# 访问数组元素
echo ${numbers[0]} # 输出第一个元素
# 遍历数组
for i in "${numbers[@]}"; do
echo $i
done
# 获取数组长度
echo "Array length: ${#numbers[@]}"
9. 关联数组
Bash 4及以上版本支持关联数组(即键值对数组)。它们的声明和使用方法如下:
declare -A fruits
fruits[apple]="red"
fruits[banana]="yellow"
# 访问关联数组元素
echo "Apple is ${fruits[apple]}"
# 遍历关联数组
for fruit in "${!fruits[@]}"; do
echo "$fruit is ${fruits[$fruit]}"
done
10. 管道和重定向
在 Shell 脚本中,管道 (|
) 和重定向 (>
, >>
, <
) 是非常重要的工具,用于数据流的控制:
# 使用管道将一个命令的输出作为另一个命令的输入
cat file.txt | grep "some text" | sort
# 重定向命令输出到文件
echo "Hello, World!" > output.txt
# 追加输出到文件
echo "Another line" >> output.txt
# 从文件中读取输入
grep "something" < input.txt
11. 调试
调试是编写脚本时的一个重要环节。在 Bash 中,你可以用 -x
选项来启动调试模式:
#!/bin/bash -x
# 上面的 shebang 与 -x 选项结合,启动脚本时会显示每一步的执行详情
# 或者在脚本中临时开启调试
set -x # 开启调试
echo "Debugging now"
set +x # 关闭调试
12. 引号的使用
在 Bash 脚本中,正确地使用引号是非常重要的,它可以影响字符串的解析和变量的展开:
- 双引号
" "
: 允许变量展开。 - 单引号
' '
: 原样输出字符串,不进行变量展开。 - 反引号
` `
: 执行里面的命令,并将输出作为值。
name="world"
echo "Hello, $name" # 输出 Hello, world
echo 'Hello, $name' # 输出 Hello, $name
echo "Today is `date`" # 输出 Today is 加当前日期
13. 文件测试运算符
文件测试运算符用于在脚本中检查文件的各种属性:
file="sample.txt"
# 检查文件是否存在
if [ -e "$file" ]; then
echo "$file exists."
fi
# 检查是否为目录
if [ -d "$file" ]; then
echo "$file is a directory."
fi
# 检查文件是否可写
if [ -w "$file" ]; then
echo "$file is writable."
fi
14. 捕获信号
在 Bash 脚本中,你可以捕获和处理来自操作系统的信号(例如 SIGINT,SIGTERM)。这使你能够在脚本接收到这些信号时执行清理操作或恢复到安全状态:
#!/bin/bash
trap 'echo "Ignoring & continuing...";' SIGINT SIGTERM
# 长时间运行的命令
while true; do
sleep 1
echo "Running..."
done
15. 子shell
在写脚本的过程中,你可能需要在子shell中运行命令。子shell是当前shell的一个独立副本,它可以执行命令而不影响主shell的环境:
#!/bin/bash
# 在子shell中执行
(result=$(cat file.txt | wc -l); echo "Lines: $result")
# 主shell的变量不受影响
echo "Outside the subshell"
16. 进程替换
进程替换是一个高级技巧,允许你把一个进程的输出作为另一个命令的输入文件处理:
#!/bin/bash
# 使用进程替换比较动态命令输出
diff <(ls /folder1) <(ls /folder2)
17. 算术运算
Bash 提供了几种方法进行算术运算:
#!/bin/bash
# 使用 (( )) 进行算术运算
x=5
y=10
(( result = x + y ))
echo $result
# 使用 let 命令
let "result = x * y"
echo $result
# 使用 $(( )) 扩展
result=$(( x - y ))
echo $result
18. Here Documents
Here Documents 是一种特殊的重定向方式,允许你将多行文本直接传递到命令中,非常适合需要多行输入的场景:
#!/bin/bash
# 使用 cat 读取多行文本
cat << EOF
这是一个 Here Document,可以包含多行文本。
你可以在这里写任何东西。
EOF
19. Here Strings
Here Strings 是 Here Documents 的简化版,允许你将单行文本重定向给命令:
#!/bin/bash
# 使用 Here String
grep "search_term" <<< "This is the string to search in."
20. IFS (Internal Field Separator)
IFS 是 Bash 中用于决定如何进行单词拆分和行的迭代的内部变量。通过修改 IFS,你可以改变 Bash 如何解释输入和输出数据:
#!/bin/bash
# 自定义 IFS 来读取逗号分隔的数据
data="one,two,three,four"
IFS=","
for item in $data; do
echo "Item: $item"
done