Shell学习(6/6) 输入/输出重定向-文件包含

发布于:2025-03-01 ⋅ 阅读:(9) ⋅ 点赞:(0)

十一、输入/输出重定向

在 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. 使用 shbash 命令

也可以使用 shbash 命令来执行另一个脚本文件。与 source 不同的是,这种方式会在子 Shell 中执行脚本,因此被包含脚本中的变量和函数不会影响当前脚本的环境。

语法:
sh filename

bash filename
示例:

继续使用上面的 utils.shmain.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. 使用 cateval

可以使用 cat 命令读取文件内容,然后通过 eval 执行这些内容。

语法:
eval "$(cat filename)"
示例:
# main.sh
eval "$(cat utils.sh)"

greet "Alice"

运行 main.sh 时,输出将是:

总结

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