[英]In Bash, how to not create the redirect output file once the command fails
通常我們可以將命令輸出重定向到文件,如下所示:
cat a.txt >> output.txt
正如我嘗試的那樣,如果cat
失敗,仍會創建output.txt
,這不是我的預期。 我知道我可以這樣測試:
if [ "$?" -ne "0"]; then
rm output.txt
fi
但是,在我的cat
執行之前已經存在這樣的output.txt
時,這可能會導致一些問題開銷。 所以我還需要在cat
之前存儲output.txt
狀態,如果在執行cat
之前已經有這樣的output.txt,我不應該錯誤地輸出output.txt
...但是在競爭條件下可能仍有問題,如果有的話進程在我的cat
非常接近之前創建這個output.txt?
那么有沒有簡單的方法,如果命令失敗,重定向output.txt將被刪除,甚至不會被創建?
固定輸出文件名是壞消息; 不要使用它們。
您可能應該重新設計處理,以便您有一個帶日期戳的文件名。 如果失敗了,你應該使用mktemp
命令創建一個臨時文件,讓你想要執行的命令寫入該命令,當命令成功時,你可以將臨時文件移動到'final'輸出 - 你可以自動清理暫時失敗。
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()
系統調用(或者甚至是一個rename()
系統調用,如果你的機器上存在這樣的東西;它只在Mac OS X上存在)。
我認為這會奏效,請查看。
[ -e output.txt ] && (mv output.txt output.txt_bkp)
cat a.txt > /dev/null 2>&1;[ $? -eq 0 ] && (cat a.txt > output.txt)
喬納森建議的另一種方式,
[ -e output.txt ] && (mv output.txt output.txt_bkp)
if cat a.txt > /dev/null 2>&1
then
cat a.txt > output.txt
fi
在命令終止之前,你無法判斷命令是否失敗,到那時它可能產生了一些輸出。
可能更有用的條件是避免創建輸出文件,直到命令實際產生一些輸出,而不用擔心它的狀態代碼。
這很接近:
command | { IFS= read -rn1 -d '' a &&
{ printf %s "$a" >> output.txt
cat >> output.txt
}
}
但是,如果通過command
輸出的第一個字符是NUL字節,則NUL將不會寫入輸出文件。 由於輸出文件的擴展名為.txt
,在這種特殊情況下不太可能,但可以通過添加命令來處理
[[ -z $a ]] && printf '\0' >> output.txt
在printf之后和貓之前。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.