
當我運行以下腳本時出現以下錯誤:
cp: cannot stat ls
腳本內容
#!/bin/bash
#make copies of all files in directory
cd /home/don
LIST='ls'
for i in $LIST; do
ORIG=$i
DEST=$i.old
cp $ORIG $DEST
echo "Copied $i"
done
有人能看到問題嗎?
答案1
主要錯誤之一是您嘗試使用該ls
命令,但變數 LIST 僅包含字串“ls”。您可以使用帶有$(command)
語法的命令替換。在這種情況下,我建議不要這樣做,因為它不會以您可以輕鬆使用的格式提供資訊。它幾乎總是一個解析輸出時發生錯誤ls
。
在這種情況下,您應該使用 shell 模式匹配,也稱為通配。
我建議在您的腳本中使用以下方法:
#!/bin/bash
#make copies of all files in directory
for i in /home/don/* ; do
if [[ -f $i ]]; then
orig="$i"
dest="${i}.old"
cp "$orig" "$dest"
echo "Copied $i"
else
echo "${i} is not a file"
fi
done
- 這使用 shell 通配來匹配目錄中的所有檔案。
./*
表示目前目錄 (.
) 中的所有內容。 - 該
if
語句檢查匹配是否是檔案(在目錄和連結上將失敗),如果是,則執行複製序列。 - 我已將變數名稱更改為小寫,因為系統環境變數是大寫,因此您將避免任何不必要的名稱衝突。
答案2
嗯,您的腳本中有一個小錯誤。在第四行你打算執行LS所以它不應該用單引號括起來,而應該包含在符號內``。所以你的腳本改變如下
LIST=`ls`
嘗試以上述方式更新您的腳本。
但是,建議$(ls)
根本不要使用,您應該更喜歡在循環頭中使用 shell 通配符。
for i in *; do
就像一樣大衛安德森先生下面評論說這可以與變數值的引號一起使用(“ $i ”)對於其後的語句,否則可能會導致檔案名稱中的空格出現問題。您可以透過將 find 與進程替換結合使用來防止這種情況:
while read l; do
i=$(basename "$l")
done < <(find . -name '*' -maxdepth 1)
下面給出了帶有腳本和解釋的詳細答案阿羅尼卡爾先生。請參考它以便將來更好地編寫腳本。
答案3
“查找”命令版本
您的腳本可以作為單行find
命令完成,無需解析ls
或弄亂 glob 等。
就問題而言,您的目標是複製目前目錄中的所有檔案。為此,適當的命令是:
find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
其作用是對(當前)目錄find
中的所有文件進行操作並調用每個文件(因此)。因為是遞歸的,所以我們必須限制搜尋的深度,因此標誌,標誌是為了避免列為搜尋結果之一。.
cp
\;
find
-maxdepth
-mindepth
.
範例運行:
$ touch "file one" "file two"
$ find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
$ ls -1
file one
file one.old
file two
file two.old
$
筆記:cp
仍然會抱怨目錄。有幾種方法可以解決這個問題。
1)如果這是您的目標,您可以僅過濾掉文件,-type f
例如find
find . -mindepth 1 -maxdepth 1 -type f -exec cp {} {}".old" \;
2)cp -r
也用於製作目錄的副本
find . -mindepth 1 -maxdepth 1 -exec cp -r {} {}".old" \;
Python 單行程式碼
這比find
那個稍微長一些,但仍然可以完成工作,並且對於特殊檔案名稱沒有問題。
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") for f in os.listdir(".") if os.path.isfile("./" + f)]'
範例運行:
$ touch "test file 1" "testfile 2"
$ python -c 'import shutil;import os;[shutil.copyfile(f,f + ".old")
> for f in os.listdir(".")
> if os.path.isfile("./" + f)]'
$ ls -1
test file 1
test file 1.old
testfile 2
testfile 2.old
$
若要包含目錄,請使用shutil.copytree(source,destination)
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") if os.path.isfile("./" + f) else shutil.copytree(f,f + ".old") for f in os.listdir(".")]'
directory_one.old/
請注意,如果 say已經存在,這將失敗