[英]Bash: Create a file if it does not exist, otherwise check to see if it is writeable
我有一個將寫入輸出文件的bash程序。 此文件可能存在也可能不存在,但腳本必須檢查權限並盡早失敗。 我無法找到一種優雅的方式來實現這一目標。 這是我嘗試過的。
set +e touch $file set -e if [ $? -ne 0 ]; then exit;fi
我保持為這個腳本set -e
,所以如果任何一行都有錯誤,它就會失敗。 有沒有更簡單的方法來執行上述腳本?
為什么復雜的事情?
file=exists_and_writeable
if [ ! -e "$file" ] ; then
touch "$file"
fi
if [ ! -w "$file" ] ; then
echo cannot write to $file
exit 1
fi
或者,更簡潔,
( [ -e "$file" ] || touch "$file" ) && [ ! -w "$file" ] && echo cannot write to $file && exit 1
而不是檢查$?
在另一行上,立即檢查返回值,如下所示:
touch file || exit
只要您的umask
不限制寫位被設置,您就可以依賴touch
的返回值
您可以使用-w
來檢查文件是否可寫(在bash手冊頁中搜索它)。
if [[ ! -w $file ]]; then exit; fi
為什么腳本必須盡早失敗? 通過將可寫測試和文件open()分開,可以引入競爭條件。 相反,為什么不嘗試打開(截斷/追加)文件進行寫入,如果發生錯誤則處理錯誤? 就像是:
$ echo foo > output.txt
$ if [ $? -ne 0 ]; then die("Couldn't echo foo")
正如其他人所提到的,如果你想避免覆蓋現有文件,那么“noclobber”選項可能會很有用。
打開文件進行寫入。 在shell中,這是通過輸出重定向完成的。 您可以通過將重定向放在內置的exec
而不帶參數的情況下重定向shell的標准輸出。
set -e
exec >shell.out # exit if shell.out can't be opened
echo "This will appear in shell.out"
確保沒有設置noclobber
選項(這在交互式中很有用,但在腳本中通常無法使用)。 如果要截斷文件(如果存在),請使用>
如果要添加,則使用>>
。
如果您只想測試權限,可以運行: >foo.out
來創建文件(如果存在則截斷它)。
如果您只想要一些命令寫入文件,請在其他描述符上打開它,然后根據需要重定向。
set -e
exec 3>foo.out
echo "This will appear on the standard output"
echo >&3 "This will appear in foo.out"
echo "This will appear both on standard output and in foo.out" | tee /dev/fd/3
( /dev/fd
在任何地方都不受支持;它至少可以在Linux,* BSD,Solaris和Cygwin上使用。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.