このスクリプトは、コマンドラインから引数として名前が付けられたすべてのファイルをユーザーのホームディレクトリにコピーする必要があります。ファイルが提供されていない場合、スクリプトは読み取りを使用してファイル名を要求し、応答に指定されたすべてのファイル名をユーザーのホームディレクトリにコピーする必要があります。
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
この特定のスクリプトには問題ありませんが、複雑なスクリプトには絶対にこれを実行しないでください。それ以外の場合は、スクリプト内のすべての変数または関数をシェルにインポートします。ただ使用bash totmp
答え2
あなたを邪魔するような問題は、コマンドがread
正しくないということです。コマンドに渡される引数は変数名でなければなりません$
($
変数の内容を拡張し、変数が空の時点で)なしで拡張する必要があります。したがって、結果はread
変数名が渡されていない状態です。)
read FILENAMES
最初のコマンドライン引数が欠落しているかどうかを確認するには、別の問題があります。存在しない場合は$1
何も(空の文字列ではない)に拡張され、コマンドに問題が発生する可能性があります[
。この場合、確認したい内容が[ -z ]
実際には無効である必要があるからです。[ -z "" ]
つまり、変数を参照する必要があります。
if [ -z "$1" ]
Bashを使用するときも使用できます[[ ... ]]
。内部コマンドなので、一般的には良いです(この場合、コマンドは引用符なしで機能する必要がありますが、引用符を保持しても問題にならず、大丈夫です)。
(PS:このスクリプトにはまだ多くのバグがあります。ベストプラクティスとは離れていて、誰かがこれを教えるのを見て本当にショックを受けました。残念ながらbashを教える基準が本当に低いようです。理解するまでは複雑なので、正しく学ぶ方法についてのより良いアドバイスがあるかどうかわかりません)。☹️
答え3
このread
コマンドは変数を受け入れますが、変数の値を引用しました。
#correct syntax
read variable
#wrong syntax
read $variable
$variable
値で、variable
スクリプトの先頭で値は設定されていません/nullです。