在Bash中,命令失败后如何不创建重定向输出文件 [英] In Bash, how to not create the redirect output file once the command fails
问题描述
通常,我们可以将命令输出重定向到文件,如下所示:
Usually we may redirect a command output to a file, as following:
cat a.txt >> output.txt
在我尝试过的情况下,如果cat
失败,仍会创建output.txt
,这不是我期望的.我知道我可以这样测试:
As I tried, if cat
failed, the output.txt
will still be created, which isn't my expected. I know I could test as this:
if [ "$?" -ne "0"]; then
rm output.txt
fi
但是,当我执行cat
之前已经有这样的output.txt
时,这可能会导致一些开销问题.
所以我还需要在cat
之前存储output.txt
状态,如果在cat
执行之前已经有这样的output.txt,我不应该错误地rm output.txt
...但是在竞争条件下仍然可能存在问题,如果有其他进程非常紧密地在我的cat
之前创建了output.txt怎么办?
But this may cause some issues overhead when there's already such output.txt
prior to my cat
execution.
So I also need store the output.txt
state before cat
, if there's already such output.txt before cat
execution, I should not rm output.txt
by mistake... but there may still be problem on race condition, what if any other process create this output.txt right before my cat
very closely?
那么有什么简单的方法,如果命令失败,重定向的output.txt将被删除,甚至没有创建?
So is there any simple way that, if the command fails, the redirection output.txt will be removed, or even not created?
推荐答案
固定的输出文件名是个坏消息.不要使用它们.
Fixed output file names are bad news; don't use them.
您可能应该重新设计该处理过程,以便获得带有日期戳的文件名.失败的话,您应该使用mktemp
命令创建一个临时文件,将要执行的命令写入该文件,当该命令成功执行后,您可以将临时文件移至最终"输出,并且可以自动执行该操作.清除故障时的临时文件.
You should probably redesign the processing so that you have a date-stamped file name. Failing that, you should use the mktemp
command to create a temporary file, have the command you want executed write to that, and when the command is successful, you can move the temporary to the 'final' output — and you can automatically clean up the temporary on failure.
outfile="./output-$(date +%Y-%m-%d.%H:%M:%S).txt"
tmpfile="$(mktemp ./gadget-maker.XXXXXXXX)"
trap "rm -f '$tmpfile'; exit 1" 0 1 2 3 13 15
if cat a.txt > "$tmpfile"
then mv "$tmpfile" "$outfile"
else rm "$tmpfile"
fi
trap 0
如果您坚持认为,可以将outfile
简化为output.txt
(但这并不安全).您可以在mktemp
命令中使用所需的任何前缀.请注意,通过在当前目录中也创建最终输出文件的当前目录中创建临时文件,可以避免在操作的mv
阶段跨设备复制文件-它是link()
和unlink()
系统
You can simplify the outfile
to output.txt
if you insist (but it isn't safe). You can use any prefix you like with the mktemp
command. Note that by creating the temporary file in the current directory, where the final output file will be created too, you avoid cross-device file copying at the mv
phase of operations — it is a link()
and an unlink()
system call (or maybe even a rename()
system call if such a thing exists on your machine; it does on Mac OS X) only.
这篇关于在Bash中,命令失败后如何不创建重定向输出文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!