【问题标题】:Printing from bash into a modified output file从 bash 打印到修改后的输出文件
【发布时间】:2022-01-01 09:42:42
【问题描述】:

我有以下脚本,check.sh:

#!/bin/bash
counter=1
while [ $counter -gt 0 ]
do
    echo "hello"
    sleep 1
done

check.sh 意味着永远运行。 假设我从终端运行代码并将其写入文件:

./check.sh > output.txt

每一秒我都会在我的文件中打印世界问候。 现在,让我们打开output.txt进行一些修改并覆盖。可执行文件check.sh 仍在运行,但它不再在output.txt 中打印。它在哪里打印?有没有办法恢复输出?

【问题讨论】:

  • 使用>> 所以> output.txt; ./check.sh >> output.txt
  • 详细说明@anubhava 评论:> 打印到覆盖其内容的文件,>> 附加到文件内容。
  • 当然。我看到>> 会起作用。但是我的问题是不同的。使用 > 后,有没有办法知道它是否仍在某处打印并恢复它,或者它确实停止打印?
  • 目前还不清楚将> 更改为>> 是否有效。事实上,我希望它不会这样做。

标签: bash output


【解决方案1】:

当您在编辑器中打开文件时,编辑器可能是 删除原始文件并创建内容并将其写入新文件 文件,尤其是当原始文件被修改时 在编辑器中打开。您可以检查文件是否被替换为新的 使用打印文件的 ls -i 选项具有相同名称的文件 inode - 在编辑器中编辑文件之前检查文件的 inode:

$ ls -i output.txt
3541644 output.txt

在编辑器中编辑后:

$ ls -i output.txt
3541637 output.txt

(您的系统上的数字会有所不同)。

它在哪里打印?

运行 check.sh 脚本并处理重定向的 Shell 将输出打印到已取消链接的文件,请参阅 this answer 了解更多 技术细节。

有没有办法恢复输出?

您没有指定您使用的操作系统,但在 Linux 上您可以使用 tail -f /proc/<PID>/fd/<NUMBER>。首先找到PID(进程标识符)的 check.sh 脚本:

$ ps aux | grep '[c]heck.sh'
ja        7476  0.0  0.0   7100  3804 pts/8    S+   14:29   0:00 /bin/bash ./check.sh`

然后打印文件描述符编号 1 (0 - 标准 输入,1 - 标准输出,2 - 标准错误):

$ tail -f /proc/7476/fd/1

注意 check.sh 输出仍然会被重定向到 output.txt 如果你 截断它而不删除它,例如通过这样做:

echo new line > output.txt

如果你使用 GNU Coreutils tail,它只会说:

tail: output.txt: file truncated

并继续打印附加的行。

【讨论】:

    【解决方案2】:

    首先考虑使用以下命令启动脚本时会发生什么:

    ./check.sh > output.txt
    

    。 shell 打开output.txt 进行写入,派生一个子进程(不一定按此顺序),将子进程的标准输出连接到打开的文件描述,然后执行脚本。如有必要,父级关闭它打开的文件描述符。

    请注意,孩子不会在每次写入时重新打开文件,甚至不知道连接到其标准输出的文件的路径(如果有的话)。

    现在,让我们打开output.txt,进行一些修改并覆盖。可执行文件check.sh 仍在运行,但它不再在output.txt 中打印。它在哪里打印?有没有办法恢复输出?

    这在一定程度上取决于“覆盖”的细节,但文本编辑器通常会创建一个新文件,在其中写入修改后的内容,然后用新文件替换原始文件。此时要明白,“替换”是指将指向原文件的目录项替换为指向新文件的一个。只要任何(硬)链接出现在任何目录中或任何进程打开它,原始文件就不会从磁盘中删除。

    现在我们可以理解脚本仍在打印到原始输出文件,但该文件(显然)不再可以在其原始路径中访问。它可能会或可能不会作为 any 路径上的文件访问,但通常不会。在某些操作系统(例如 Linux)上,只要脚本继续运行,脚本的标准输出可能可以作为特殊文件系统中的条目访问,但它可能是只写的,即使在这种情况下,它也不是可以恢复已写入那里的任何数据。

    仍有可能发现底层物理文件并访问其内容,但这需要特殊工具。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2022-07-27
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      相关资源
      最近更新 更多