簡單的 bash 腳本不起作用

簡單的 bash 腳本不起作用

此腳本應將名稱在命令列上作為參數提供的所有檔案複製到使用者主目錄。如果未提供文件,則腳本應使用 read 來詢問文件名,並將答案中提供的所有文件名稱複製到使用者主目錄。

if [ -z $1 ]
then
    echo provide filenames
    read $FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

如果我提供字串形式的參數 - 它可以工作。但如果我提供“讀取$FILENAMES” - 它不起作用。

導師在他的課程中展示了相同的解決方案,但沒有展示它是如何運作的。 在此輸入影像描述

更新在我輸入文件名作為參數後,它給出空字串並且沒有將文件複製到 $HOME 位置

[dmytro@oc1726036122 ~]$ cd Desktop/
[dmytro@oc1726036122 Desktop]$ . totmp 
provide filenames
one two
the following filenames have been provided:
the following filenames have been provided:
[dmytro@oc1726036122 Desktop]$

答案1

宣告read變數而不是讀取它們。簡而言之,刪除其中的$內容read就可以了。

if [ -z $1 ]
then
    echo provide filenames
    read FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

編輯:我看到您使用source( .) 命令來運行腳本。

[dmytro@oc1726036122 Desktop]$ . totmp

對於這個特定的腳本來說可能沒問題,但對於複雜的腳本永遠不要這樣做。否則,您將從該腳本中獲取任何變數或函數到您的 shell 中。只需使用bash totmp

答案2

似乎阻礙您的問題是命令read不正確,傳遞給它的參數應該是變量名,因此應該在沒有$($將擴展變量的內容,此時變量為空,所以結果是 a read,沒有傳遞任何變量名。)

read FILENAMES

檢查是否缺少第一個命令列參數還有另一個問題。如果它不存在,則將$1擴展為空(不是空字串),這可能會導致命令出現問題[,因為在這種情況下您希望檢查的內容[ -z ]實際上並不應該是有效的。[ -z "" ]簡而言之,您需要引用該變數:

if [ -z "$1" ]

當您使用 bash 時,您也可以使用[[ ... ]],這通常更好,因為它是一個內部命令(在這種情況下,該命令應該在沒有引號的情況下工作,但保留引號不會造成傷害並且看起來不錯。

(PS:這個腳本還有很多錯誤,它離最佳實踐還很遠,看到有人教這個我真的很震驚。不幸的是,似乎教授bash 的門檻真的很低,而且手冊也很複雜,直到你實際上理解得很好,所以我也不知道我對如何正確學習它有更好的建議。☹️

答案3

read命令接受變量,但您已經引用了變數的值:

 #correct syntax
 read variable
 #wrong syntax
 read $variable

$variable是 的值variable,並且在腳本的開頭,該值未設定/為空。

相關內容