十一、输入/输出重定向
在 Shell 脚本中,输入/输出重定向是一种强大的功能,允许你将命令的输入和输出从默认的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)重定向到文件或其他命令。
1. 标准输出重定向 (> 和 >>)
>:将命令的标准输出重定向到文件。如果文件已存在,内容会被覆盖。
echo "Hello, World!" > output.txt
将 Hello, World! 写入 output.txt 文件。如果 output.txt 已存在,原有内容会被覆盖。
>>:将命令的标准输出追加到文件末尾。如果文件不存在,会创建新文件。
echo "Hello again!" >> output.txt
将 Hello again! 追加到 output.txt 文件的末尾,而不会覆盖原有内容。

2. 标准错误重定向 (2> 和 2>>)
2>:将命令的标准错误重定向到文件。如果文件已存在,内容会被覆盖。
ls /nonexistent_directory 2> error.txt
如果目录不存在,错误信息会被写入 error.txt 文件。

2>>:将命令的标准错误追加到文件末尾。如果文件不存在,会创建新文件。
ls /another_nonexistent_directory 2>> error.txt
错误信息会被追加到 error.txt 文件的末尾。

3. 同时重定向标准输出和标准错误 (&> 和 &>>)
&>:将标准输出和标准错误都重定向到文件。如果文件已存在,内容会被覆盖。
ls /nonexistent_directory &> output_and_error.txt
无论命令成功还是失败,输出和错误信息都会被写入 output_and_error.txt 文件。

&>>:将标准输出和标准错误都追加到文件末尾。如果文件不存在,会创建新文件。
ls /another_nonexistent_directory &>> output_and_error.txt
输出和错误信息会被追加到 output_and_error.txt 文件的末尾。

4. 标准输入重定向 (<)
<:将文件内容作为命令的标准输入。
wc -l < input.txt
会计算 input.txt 文件的行数。

5. 管道 (|)
|:将一个命令的标准输出作为另一个命令的标准输入。
ls -l | grep "txt"
这会列出当前目录下的所有文件,并将输出传递给 grep 命令,筛选出包含 txt 的行。

6. 重定向到 /dev/null
/dev/null:将输出或错误重定向到/dev/null,相当于丢弃输出。
ls /nonexistent_directory 2> /dev/null
会将错误信息丢弃,不会显示在终端上。
7. Here Document (<<)
<<:用于将多行输入传递给命令。
cat << EOF
This is line 1.
This is line 2.
EOF
这会将两行文本传递给 cat 命令,输出如下:

8. Here String (<<<)
<<<:用于将字符串作为输入传递给命令。
grep "foo" <<< "foo bar baz"
这会将字符串 foo bar baz 作为输入传递给 grep 命令,输出 foo。

9. 重定向顺序(看不懂)
- 重定向的顺序很重要。例如:
command > file 2>&1
- 这会将标准输出和标准错误都重定向到
file。
command 2>&1 > file
这只会将标准输出重定向到 file,而标准错误仍然输出到终端。
10. 重定向到文件描述符(看不懂)
- 可以使用文件描述符(如
3)来创建自定义的重定向。
exec 3> output.txt
echo "Hello, World!" >&3
exec 3>&-
这会将 Hello, World! 写入 output.txt 文件,然后关闭文件描述符 3。
十二、文件包含
在 Shell 脚本中,文件包含(File Inclusion)是指在一个脚本中引入并执行另一个脚本的内容。可以帮助你将代码模块化,提高代码的复用性和可维护性。Shell 本身并没有像其他编程语言(如 C 或 Python)那样的专门的文件包含机制,但可以通过以下几种方式实现类似的功能。
1. 使用 source 命令
source 命令(或 . 命令)用于在当前 Shell 环境中执行指定脚本文件中的命令。这意味着被包含的脚本中的变量、函数等会在当前脚本中生效。
语法:
source filename
或
. filename
示例:
假设有一个脚本 utils.sh,内容如下:
# utils.sh
greet() {
echo "Hello, $1!"
}
在另一个脚本 main.sh 中,你可以通过 source 命令包含 utils.sh:
# main.sh
source utils.sh
greet "Alice"
运行 main.sh 时,输出将是:(失误,少打个 s )

2. 使用 sh 或 bash 命令
也可以使用 sh 或 bash 命令来执行另一个脚本文件。与 source 不同的是,这种方式会在子 Shell 中执行脚本,因此被包含脚本中的变量和函数不会影响当前脚本的环境。
语法:
sh filename
或
bash filename
示例:
继续使用上面的 utils.sh 和 main.sh,但这次使用 bash 命令:
# main.sh
bash utils.sh
greet "Alice"
运行 main.sh 时,会报错,因为 greet 函数在子 Shell 中定义,不会在当前 Shell 中生效。

3. 使用 exec 命令
exec 命令可以用于替换当前 Shell 进程为指定的命令或脚本。这意味着当前脚本的执行会停止,转而执行被包含的脚本。
语法:
exec filename
示例:
# main.sh
echo "This will not be executed"
exec bash utils.sh
echo "This will not be executed either"

4. 使用 cat 和 eval
可以使用 cat 命令读取文件内容,然后通过 eval 执行这些内容。
语法:
eval "$(cat filename)"
示例:
# main.sh
eval "$(cat utils.sh)"
greet "Alice"
运行 main.sh 时,输出将是:

总结
在 Shell 脚本中,文件包含可以通过多种方式实现,最常见的是使用 source 或 . 命令。这种方式允许你在当前 Shell 环境中执行另一个脚本,使得变量、函数等可以在当前脚本中使用。

1243

被折叠的 条评论
为什么被折叠?



