簡體   English   中英

如果文件不存在,如何執行某些命令?

[英]How to execute certain commands if a file does NOT exist?

我想檢查文件是否存在,如果不存在,則創建它。

考慮使用以下C代碼,但使用shell腳本。

if(!exist) {
    command;
    command;
}
else {
    command;
    command;
}

檢查文件是否存在是一項非常常見的任務。 要搜索相關問題,請使用搜索欄(右上角)。 我用術語“bash腳本文件存在”得到了很多結果

在任何情況下,您都需要test內置或其語義等價物[ ]

[ ! -e your_file ] && >your_file

要么

test ! -e your_file && >your_file

這將首先test your_file不存在( ! )(- -e )並創建它(如果是這種情況)。

有關可以運行的不同測試的更多信息(除了-e ),您可以鍵入:

help -m test | less

你可以用這個:

if [ ! -e "$file" ]; then
       touch file
else
        ...
fi
if [ ! -e "$path" ]
then
    touch -- "$path"
fi

一個更簡單的版本就是簡單地touch -- "$path" - 它創建文件(如果它不存在),只是更新訪問和修改時間(如果它存在)。 雙短划線-- )確保您可以創建文件,即使它以短划線開頭,並且$path周圍的引號也是必需的。

不要這樣做,它不僅受競爭條件的限制,而且[ -e /path/file ]檢查你是否可以對文件執行stat(2) ,因此它會因不同的原因返回false,不僅如此因為文件不能存在。

一個示例是不存在的文件的符號鏈接或您沒有搜索權限的目錄中的文件。

更好的方法是在這里使用open(2)系統調用的正確標志,即O_CREAT|O_EXCL 這樣,如果文件不存在, open()失敗,而您不必先檢查數百萬個CPU時鍾周期。

使用類似Bourne的shell:

if (set -C && : > "$file") 2> /dev/null; then
  print '%s\n' "$file has been created
else
  print '%s\n' "It hasn't, possibly because it was already there"
fi

set -C是為了啟用O_EXCL標志)。

另外,為什么要創建一個空文件? 您可能希望在該文件中存儲某些內容。 然后,就這樣做:

set -C
{
  echo blah
  other-commands that-generate-the-content
} > "$file"

然后,只有在file不存在的情況下才會執行該命令組(並且可以創建它)。

如果要測試文件是否存在,請至少寫入:

[ -e "$file" ] || [ -L "$file" ]

要么

ls -d -- "$file" > /dev/null 2>&1

如果你關心它可能是一個符號鏈接。 如果文件確實存在但您無權對其進行驗證,那么仍將返回false。


現在,如果您想要有關測試文件存在的更長且歷史性的答案:

最初, test命令(在它首次出現的Unix v7中) 沒有-e (也不是-h / -L選項或-a一元)選項。

測試文件存在的方法是使用ls ls (帶-d )列出文件並報告錯誤(並返回錯誤的退出狀態),如果由於某種原因無法查找文件。 Unix最初沒有符號鏈接,但是當它們被引入時, ls被修改為對文件而不是stat(2)執行lstat(2) stat(2) 也就是說,在symlink ls情況下, ls返回有關符號鏈接文件本身的信息,而不是符號鏈接指向的路徑上的文件。

test (aka [ )測試文件“存在”的選項最初是在Korn shell test內置中引入的。 那是-a ,而不是-e -a可訪問的 (我相信),這是一個比現有更准確的術語。

我不知道何時或什么介紹-e ,可能是POSIX。 POSIX 表示 -e被選中-a以避免與-a 二元運算符(for )混淆。

在任何情況下, -a-e都在文件上嘗試stat(2) ,而不是lstat(2) 那是:

[ -e "$file" ]

相當於:

ls -Ld -- "$file" > /dev/null 2>&1

因此,嚴格地說,如果在測試完成時,可以在解析符號鏈接后查找路徑,並且如果stat(2)失敗,則忽略失敗的原因,它返回true。

如果文件不存在( ENOENT ),則stat可能會失敗,即文件不存在或存在但是對於不存在的文件的符號鏈接,但也有很多其他原因。 查看stat(2)的可能錯誤代碼可以提供一些想法:

  • EACCESS :在解析路徑期間(可以是任何路徑組件和任何符號鏈接的路徑),您沒有一個目錄組件的搜索權限(請注意,您可能仍然可以通過另一個路徑訪問該文件) 。
  • ELOOP :無法解決這條路徑,因為太多的符號鏈接已經解決了。
  • ENOTDIR 例如在/etc/passwd/foo或它的符號鏈接上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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