如果我的程序崩溃,我想避免出现临时文件。
UNIX 的奇妙之处在于您可以使文件保持打开状态 - 即使在删除它之后也是如此。
因此,如果您打开该文件,请立即将其删除,然后然后进行缓慢的处理,即使程序崩溃,用户也很有可能不必清理文件。
在 shell 中我经常看到类似的东西:
generate-the-file -o the-file
[...loads of other stuff that may use stdout or not...]
do_slow_processing < the-file
rm the-file
但如果程序崩溃之前rm
用户就必须进行清理the-file
。
在 Perl 中你可以这样做:
open(my $filehandle, "<", "the-file") || die;
unlink("the-file");
while(<$filehandle>) {
# Do slow processing stuff here
print;
}
close $filehandle;
然后文件一打开就会被删除。
shell中有类似的构造吗?
答案1
这在 csh、tcsh、sh、ksh、zsh、bash、ash、sash 中进行了测试:
echo foo > the-file
(rm the-file; cat) < the-file | do_slow_processing
do_other_stuff
或者如果您愿意:
(rm the-file; do_slow_processing) < the-file
do_other_stuff
有趣的是,它也适用于 fifo:
mkfifo the-fifo
(rm the-fifo; cat) < the-fifo | do_slow_processing &
echo foo > the-fifo
这是因为在写入内容之前,读者会被阻塞。
答案2
generate-the-file > the-file
exec 5< the-file
rm the-file
...
do_slow_processing 0<&5
笔记:
- 您需要在没有可执行文件的情况下运行 exec,因此它会影响 shell 本身的描述符
- 最多仅提供 9 个 fd
- 如果需要文件名,可以使用 /proc/self/fd/X 。此接口不可在 UNIX 风格之间移植(不过它可能适合您)。
- 尝试再次读取 fd(例如两次调用
cat 0<&5
)将会失败,因为您处于 EOF 位置。您需要倒带它,或者通过阅读来克服它/proc/self/fd/X
- 在上面的大多数情况下,您可以在没有实际文件的情况下进行操作,但可以执行一个简单的操作
generate-the-file | do_slow_processing
更新:
OP 提到generate-the-file
可能不会在标准输出中产生输出。对此有一些习语:
- 指定输出文件
-
.通常接受输出文件名 - 表示 stdout。这是经 POSIX.1-2017 认可:准则 13: 对于使用操作数来表示要打开以进行读取或写入的文件的实用程序,“-”操作数应仅用于表示标准输入(或标准输出,当从上下文中清楚地知道正在指定输出文件时)或文件名为-.
(对于那些明确定义的实用程序之外的实用程序,它是实现定义的,但很有可能您的generate-the-file
工具支持它)
使用
/dev/stdout
或/proc/self/fd/1
.取决于操作系统,请参阅/dev/stdin、/dev/stdout 和 /dev/stderr 的可移植性如何?使用进程替换。 bash 将允许您写入
>(process substitution)
文件名。例如:wget -O >(rot13 > Question.txt)https://unix.stackexchange.com/q/579535/70346
这不适用于所有 shell,并且需要操作系统支持 fd 文件名。
答案3
在bash
shell 中,处理清理的方法是使用trap
内置的 EXIT(在bash
shell 中键入help trap
):
trap 'rm temp-file' EXIT
此功能也存在于dash
shell 中,sh
在现代 Linux 发行版中经常被称为别名。