或者我应该关闭文件 - 然后安装覆盖 - 然后再次重新打开文件? IE
#!/bin/bash
my_background_process >log.txt &
...
pkill my_background_process
mount overlay
my_background_process >>log.txt &
...
有必要吗?
答案1
文件打开后,它将保持打开状态,直到进程将其关闭。从文件中读取和写入并不关心该文件是否仍以其原始名称可用。该文件可能已被重命名、删除、隐藏……它仍然是同一个文件。
如果您打开一个文件/somewhere/somefile
,然后在 挂载一个文件系统/somewhere
,那么之后/somewhere/somefile
将在新文件系统上指定一个文件。但这仅在您打开时才重要/somewhere/somefile
。如果一个进程已经/somewhere/somefile
在原始文件系统上打开,则不会改变。
当 shell 处理重定向运算符时,重定向会打开一个文件。此后,即使涉及多个进程,它仍然是同一个打开的文件。例如,在下面的代码片段中,program2
写入/mnt/log.txt
根分区上的文件 at ,而program3
写入/log.txt
on /dev/something
。
do_stuff () {
program1
mount /dev/something /mnt
program2
program3 >/mnt/log.txt
}
do_stuff >/mnt/log.txt
如果您已经启动了一个程序并且想要更改其输出的位置,则需要要求该程序执行此操作。理论上,您可以使用调试器强制程序执行此操作 - 这个线程列出了一些可以做到这一点的程序。但是,对这样的程序进行深入研究可能会导致程序崩溃。
如果您确实需要更改程序输出的中途位置,则需要通过能够更改其自身输出的助手来中继输出。这是 shell 脚本中的一个微小的概念验证:
my_background_process | {
while IFS= read -r line; do
printf '%s\n' "$line" >>/mnt/log.txt
done
} &
该脚本打开每一行的输出文件,因此如果 指定的文件发生/mnt/log.txt
更改(因为文件已被移动,因为新的文件系统已安装在/mnt
等),则后续行将被写入新文件。请注意,您需要指定目录的名称:使用 just >log.txt
,这将始终打开当前目录中的文件,因此它不会受到安装操作的影响(当前目录的工作方式就像打开的文件:将某些内容安装在/mnt
不会影响进程将其视为当前目录,即使它们的当前目录是/mnt
)。
答案2
Linux 不支持自动重定向在任意文件系统上打开的文件。有必要自己这样做。