在 bash 脚本中保持文件永远打开
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3462075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Keep a file open forever within a bash script
提问by User1
I need a way to make a process keep a certain file open forever. Here's an example of what I have so far:
我需要一种方法来使某个进程永远打开某个文件。这是我到目前为止所拥有的一个例子:
sleep 1000 > myfile &
sleep 1000 > myfile &
It works for a thousand seconds, but really don't want to make some complicated sleep/loop statement. This postsuggested that catis the same thing as sleepfor infinite. So I tried this:
它工作了一千秒,但真的不想做一些复杂的睡眠/循环语句。这篇文章表明这cat与sleep无限相同。所以我试过这个:
cat > myfile &
cat > myfile &
It almost looks like a mistake doesn't it? It seemed to work from the command line, but in a script the file connection did not stay open. Any other ideas?
它几乎看起来像是一个错误,不是吗?它似乎从命令行工作,但在脚本中文件连接没有保持打开状态。还有其他想法吗?
采纳答案by DVK
The reason that cat>myfile&works is because it re-directs standard input into a file.
有效的原因cat>myfile&是因为它将标准输入重定向到文件中。
if you launch it with an ampersand (in background), it won't get ANY input, including end-of-file, which means it will forever wait and print nothing to the output file.
如果您使用&符号(在后台)启动它,它将不会获得任何输入,包括文件结尾,这意味着它将永远等待并且不会向输出文件打印任何内容。
You can get an equivalent effect, except WITHOUT dependency on standard input (the latter is what makes it not work in your script), with this command:
您可以获得等效的效果,除了不依赖于标准输入(后者使其在您的脚本中不起作用),使用以下命令:
tail -f /dev/null > myfile &
回答by psmears
Rather than using a background process, you can also just use bash to open one of its file descriptors:
除了使用后台进程,您还可以使用 bash 打开其文件描述符之一:
exec 5>myfile
(The special use of exechere allows changing the current file descriptor redirections - see man bashfor details). This will open file descriptor 5 to "myfile" (use >>if you don't want to empty the file).
(exec此处的特殊用途允许更改当前文件描述符重定向 -man bash有关详细信息,请参阅)。这将打开文件描述符 5 到“myfile”(>>如果您不想清空文件,请使用)。
You can later close the file again with:
您可以稍后再次关闭文件:
exec 5>&-
(One possible downside of this is that the FD gets inherited by every program that the shell runs in the meantime. Mostly this is harmless - e.g. your greps and seds will generally ignore the extra FD - but it could be annoying in some cases, especially if you spawn any processes that stay around (because they will then keep the FD open).
(这样做的一个可能的缺点是 FD 被 shell 同时运行的每个程序继承。大多数情况下这是无害的 - 例如,您的greps 和seds 通常会忽略额外的 FD - 但在某些情况下可能会很烦人,尤其是如果您产生任何留在周围的进程(因为它们将使FD保持打开状态)。
回答by ralfw
On the cat > myfile &issue running in terminal vs not running as part of a script: In a non-interactive shell the stdinof a backgrounded command &gets implicitly redirected from /dev/null.
在cat > myfile &在终端中运行VS不运行的脚本的一部分问题:在非交互的shell的stdin一个背景执行的command &被隐式地从重定向/dev/null。
So, cat > myfile &in a script actually gets translated into cat </dev/null > myfile, which terminates catimmediately.
因此,cat > myfile &在脚本中实际上被翻译成cat </dev/null > myfile,并cat立即终止。
See the POSIX standard on the Shell Command Language & Asynchronous Lists:
请参阅 Shell 命令语言和异步列表上的 POSIX 标准:
The standard input for an asynchronous list, before any explicit redirections are
performed, shall be considered to be assigned to a file that has the same
properties as /dev/null. If it is an interactive shell, this need not happen.
In all cases, explicit redirection of standard input shall override this activity.
# some tests
sh -c 'sleep 10 & lsof -p ${!}'
sh -c 'sleep 10 0<&0 & lsof -p ${!}'
sh -ic 'sleep 10 & lsof -p ${!}'
# in a script
- cat > myfile &
+ cat 0<&0 > myfile &
回答by strager
tail -f myfile
This 'follows' the file, and outputs any changes to the file. If you don't want to see the output of tail, redirect output to /dev/nullor something:
这“跟随”文件,并输出对文件的任何更改。如果您不想看到 的输出,请将输出tail重定向到/dev/null或其他内容:
tail -f myfile > /dev/null
You may want to use the --retryoption, depending on your specific case. See man tailfor more information.
您可能希望使用该--retry选项,具体取决于您的具体情况。请参阅man tail以获取更多信息。

