簡體   English   中英

在Bash中,一旦命令失敗,如何不創建重定向輸出文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM