我想在shell腳本中獲得以下C代碼的等效代碼。如何在文件不存在的情況下執行某些命令?
if(!exist) {
command;
command;
}
else {
command;
command;
}
我想更準確地在這個shell腳本中檢查文件是否存在,然後創建它。
另外,我真的很抱歉,如果這是另一個問題的重複,但我真的不知道如何搜索它。
我想在shell腳本中獲得以下C代碼的等效代碼。如何在文件不存在的情況下執行某些命令?
if(!exist) {
command;
command;
}
else {
command;
command;
}
我想更準確地在這個shell腳本中檢查文件是否存在,然後創建它。
另外,我真的很抱歉,如果這是另一個問題的重複,但我真的不知道如何搜索它。
您可以使用此:
if [ ! -e "$file" ]; then touch file else ... fi
race-condition-city,有沒有辦法使用一個標誌,比如'touch -e file',如果該文件已經存在,它會以1退出? –
if [ ! -e "$path" ]
then
touch -- "$path"
fi
一個簡單的版本是簡單地touch -- "$path"
- 它會創建文件,如果它不存在,如果確實存在,它只是更新的訪問和修改時間。 double dash(--
)確保您可以創建該文件,即使它以破折號開頭,quotes約$path
是必要的。
非常感謝!我無法接受解決方案,因爲我沒有足夠的聲望 –
檢查文件是否存在,是一種很常見的任務。要搜索相關問題,請使用搜索欄(右上角)。我lots of results與術語「bash腳本文件存在」
在任何情況下,你想要麼test
內置或者其語義等效[ ]
:
[ ! -e your_file ] && >your_file
或
test ! -e your_file && >your_file
這將第一test
your_file
不存在(!
)存在(-e
)並創建它,如果是這種情況。
有關不同的測試,你可以運行(除-e
等)的更多信息,你可以輸入:
help -m test | less
您也可以使用短路評估,如'[-e your_file] || > your_file' – Useless
不要做,它不僅受競爭條件,而且還[ -e /path/file ]
檢查如果你可以在一個文件上做一個stat(2)
,所以它會因爲不同的原因返回false,這不僅僅是因爲文件不能存在。
一個示例是不存在的文件的符號鏈接,或者您不具有搜索權限的目錄中的文件。
一個更好的方法是在這裏使用正確的標記來調用open(2)
系統調用,即O_CREAT|O_EXCL
。這樣,如果文件不存在,open()
會失敗,而您不必先檢查幾百萬個CPU時鐘節拍。
隨着類似Bourne殼:
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它第一次出現)had no -e
(nor -h
/-L
option or -a
unary)選項。
測試文件存在的方法是使用ls
。 ls
(與-d
)列出該文件並報告錯誤(並返回錯誤退出狀態),如果由於某種原因無法查找該文件。 Unix最初沒有符號鏈接,但是當它們被引入時,ls
被修改爲在文件上執行lstat(2)
而不是stat(2)
。也就是說,如果符號鏈接ls
返回有關符號鏈接文件本身的信息,而不是符號鏈接指向的路徑中的文件。
到test
(又名[
)進行測試的選項文件「存在」首先在Korn shell test
builtin介紹。那是-a
,而不是-e
。 -a
適用於(我相信)這是一個比現有更準確的術語。
我不知道什麼時候介紹-e
,可能是POSIX。 POSIX says,-e
被選爲-a
以避免與-a
二進制運營商(對於和)可能的混淆。
在任何情況下的文件,而不是一個lstat(2)
都-a
和-e
嘗試stat(2)
。那就是:
[ -e "$file" ]
等同於:
ls -Ld -- "$file" > /dev/null 2>&1
所以,嚴格來說,它返回true,如果在測試做的時候,有可能解決的符號鏈接後查找路徑,如果stat(2)
失敗,則忽略失敗的原因。
stat
如果該文件不存在(ENOENT
),即文件不存在或存在,但是它是不存在的文件的符號鏈接,但也有很多其他原因可能會失敗。看着the possible error codes of stat(2)
給出了幾點建議:
EACCESS
:路徑的分辨率時(這可以是任何路徑組件,並在任何符號鏈接的路徑),你不必搜索權限一個目錄組件(請注意,您可能仍然可以通過其他路徑訪問該文件)。ELOOP
:由於太多符號鏈接解析到達那裏,因此無法解析路徑。ENOTDIR
。例如在/etc/passwd/foo
或其符號鏈接。聲稱它的競爭條件是不成熟的。 OP沒有說明這個文件來自哪裏,腳本可能是唯一能夠創建它的東西。還說不應該使用'[-e/path/file]',因爲它可能會錯誤地失敗並不是一個好的參數。如果測試錯誤地失敗並嘗試創建文件,則創建將會出錯。通過刪除測試並使用O_EXCL,創建將會出現與測試具有完全相同原因的錯誤。另外它可能是一個創建文件的程序,其中'set -C'不會阻止程序覆蓋它。 – Patrick
@Patrick。否,如果文件是符號鏈接到現有目錄中不存在的文件,則「[-e」$ file「]'將返回false,則創建將成功,而不會生成O_EXCL(這是危險的,因爲攻擊者可以強制您創建文件,你不會想要),並會失敗,O_EXCL(這意味着沒有關注)。 –
另外,對於OP來說可能是「過早」。很可能他一次只運行腳本的一個實例,沒有別的東西可以寫入該文件,該文件處於非常溫和的區域,只有一個用戶有寫入權限,並且該用戶永遠不會涉及處理「外國/外來/不受控制」的數據,但是在堆棧交換中,答案是針對每個人的,因此IMO應該指出風險。並且考慮到該方法更安全且更便宜(只有一個系統調用,儘管第一次分叉,沒有外部命令運行),該方法應該是優選的。 –
如果你對bash腳本感興趣,很好的資源是http://www.tldp.org/LDP/abs/abs-guide.pdf –
謝謝你,隊友!說實話,我認爲這將是Stack Exchange的正確部分來回答這類問題。 –
它是正確的地方。你的問題是關於這裏的話題,@Patrick shell腳本是明確的[在主題](http://unix.stackexchange.com/help/on-topic)。 SO shell腳本問題很容易在噪聲中丟失,你可以問他們哪裏感覺更舒適。 – terdon