[英]Shell recognizes files in ~ but not in ~/Documents
我正在上Unix類,這是我的作業的一部分:
對於用戶的〜/ Documents目錄中的每個文件和子目錄,請確定該項目是文件還是目錄,並使用語句中的文件名顯示相應的消息。
所以,我寫的是這樣的:
docs=`ls ~/Documents`
for file in $docs ; do
if [ -f $file ] ; then
echo $file "is a file."
elif [ -d $file ] ; then
echo $file "is a directory."
else
echo $file "is not a file or directory."
fi
done
我的文檔目錄包括以下文件和目錄:
DocList.txt (file)
Letter (file)
mypasswdfile (file)
samples (directory)
things (directory)
touchfile (file)
所以我想輸出應該是這樣的:
DocList.txt is a file.
Letter is a file.
mypasswdfile is a file.
samples is a directory.
things is a directory.
touchfile is a file.
但是,這是輸出:
DocList.txt is not a file or directory.
Letter is not a file or directory
mypasswdfile is not a file or directory
samples is not a file or directory
things is not a file or directory
touchfile is not a file or directory
我想我應該提一下,如果將$ docs變量設置為`ls〜',它將成功顯示主目錄的內容以及項目是文件還是目錄。 這不適用於我嘗試過的其他路徑。
問題是您的ls
命令-您將ls
的輸出視為絕對,例如/home/alex/Documents/DocList.txt
,但是當您執行DocList.txt
ls ~/Documents
它將輸出DocList.txt
(相對文件路徑/名稱)。
要獲得預期的絕對行為,可以使用find
命令代替:
docs=`find ~/Documents`
如評論和另一個答案中所述,要能夠處理文件名中的空格,您需要執行以下操作:
docs=( ~/Documents/* )
for f in "${docs[@]}"; do
...
您的問題是ls
僅輸出不帶路徑的文件名。
所以你的$file
得到值
DocList.txt
Letter
mypasswdfile
samples
things
touchfile
從循環運行到循環運行。
如果您的當前目錄不是~/Documents
,則測試這些文件名是錯誤的,因為這將在當前目錄中搜索而不是在預期目錄中搜索。
完成任務的更好方法是
for file in ~/Documents/* ; do
...
done
這會將$file
設置$file
查找文件所需的每個完整路徑名。
這樣做之后,它應該可以工作,但是很容易出錯:一旦路徑或文件之一開始包含空格或其他空白字符,它就會落在您的腳上。
將"
放在可能包含空格等東西的變量周圍非常必要。幾乎沒有理由在沒有變量的情況下使用變量"
。
這里有什么區別?
使用[ -f $file ]
和file='something with spaces'
, [
將使用-f
, something
, with
, spaces
和]
參數調用。 這肯定會導致錯誤的行為。
OTOH,帶有[ -f "$file" ]
和file='something with spaces'
, [
被稱為-f
, something with spaces
和]
。
因此,引用在Shell編程中非常重要。
當然, [ -d "$file" ]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.