我想编写一个 Bash 脚本,其中有两个
.sh
文件:
main.sh
- 主脚本,其中我将下标称为 subscripts/checksum.sh
并将其结果写入名为 checksum
subscripts/checksum.sh
- 返回比较两个文本文件内容的 diff
命令输出的脚本(它们不同,因此在我的示例中 diff
命令将始终返回带有一些描述的非零退出代码)$ tree .
.
├── main.sh
└── subscripts
├── checksum.sh
├── file1.sha512sum.txt
├── file1.txt
├── file2.sha512sum.txt
└── file2.txt
2 directories, 6 files
main.sh
:#!/bin/bash
set -e
echo "*** Before checksum"
checksum=$(subscripts/checksum.sh)
echo "*** After checksum"
echo "Checksum value: ${checksum}"
subscripts/checksum.sh
:#/bin/bash
set -e
checksum1=subscripts/file1.sha512sum.txt
checksum2=subscripts/file2.sha512sum.txt
echo "----- Before diff"
if diff_res=$(diff ${checksum1} ${checksum2})
then
echo "Checksums are equal."
else
echo "There is a difference between the checksums."
fi
echo "----- After diff"
echo ${diff_res}
执行
main.sh
给出以下结果:
*** Before checksum
*** After checksum
Checksum value: ----- Before diff
There is a difference between the checksums.
1c1 < a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt --- > 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
----- After diff
1c1 < a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt --- > 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
似乎
main.sh
中的每个命令都已先运行,然后是subscripts/checksum.sh
中的命令。这是为什么?我怎样才能得到正确的结果(如下所述)?
通过正确的结果,我的意思是打印
*** Before checksum
,然后进入subscripts/checksum.sh
并执行从第一个到最后一个的所有命令,将所有三个echo
命令打印到控制台,然后分配diff_res
的值到 checksum
中的 main.sh
。整个动作应该以最后一个打印结束,即*** After checksum
。在我的示例中, checksum
变量应该具有值:
1c1
< a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt
---
> 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
*** Before checksum
----- Before diff
There is a difference between the checksums.
----- After diff
*** After checksum
Checksum value: 1c1
< a5f4d3e657ad3ef1b208e16f47b6d766cf3e2f1db8d6b5c0d2bf0573d10eb2fefcc75c9f91d5f4e047fa9a7d00848911477005015052f7005a2b85eeb8c4eabf file1.txt
---
> 576bfc364f00634e8227f71fdf379168e4c3ee013da9eae2bdcdb905746b8514a959a9c01a8f11b8ea62a67ba08a3041a46b8065b73bdaad754e1d6153131896 file2.txt
如果我理解正确,您希望看到之前/之后的行(忽略其他行)按以下顺序打印:
*** Before checksum
----- Before diff
----- After diff
*** After checksum
但实际上是按这个顺序打印的:
*** Before checksum
*** After checksum
----- Before diff
----- After diff
这是因为你编写 main.sh 的方式。你写了这个:
checksum=$(subscripts/checksum.sh)
这意味着
checksum.sh
的输出,包括Before diff
和After diff
行,不会立即打印。它将存储在一个变量中以便稍后访问。
换句话说,您的代码遵循以下步骤:
*** Before checksum
checksum.sh
并存储其输出(输出有 Before diff
和 After diff
)*** After checksum
Checksum value:
这就是为什么行的显示顺序与您想要的不同。
如果您希望
checksum.sh
将 Before diff
和 After diff
直接打印到终端,而不将这些行存储在变量中,则应该像这样更改 checksum.sh
:
echo "----- Before diff" >&2
...
echo "----- After diff" >&2
这是有效的,因为默认情况下,所有输出都会发送到 stdout,它可以使用
$()
存储在变量中。但是使用 >&2
将输出发送到 stderr,该输出显示在终端中,而不是由 $()
存储。