私はあなたのスクリプトをbashイディオムを使って書き直しました:
#!/bin/bash
#This script distributes file/folders to all POP servers within the production environment.
echo "Are you willing to transfer a file or a directory? [Answer: file/dir]"
read -r answer
echo "Please enter a file name or a full path to the files/directories you want to distribute"
read -r locfile
echo "Please enter the destination path"
read -r destfile
if [[ -n "$answer" ]] then
case "$answer" in
file)
while read -r srv; do
[[ -n "$srv" ]] || continue
echo "$srv:"
/usr/bin/scp -- "$locfile" "$srv:$destfile"
done < ~/srv.lst
;;
dir)
while read -r srv; do
[[ -n "$srv" ]] || continue
echo "$srv:"
/usr/bin/scp -r -- "$locfile" "$srv:$destfile"
done < ~/srv.lst
;;
*)
echo "Please check your input"
;;
esac
fi
変化したこと?より多くの引用符(ファイル名にスペースが含まれていると、スクリプトは遅かれ早かれ壊れるでしょう)と[[...]]
、非推奨で堅牢性の低い(bashで)の代わりに使用し[...]
ます。オプションも使用read
しました-r
(バックスラッシュが文字をエスケープできないようにするため)。私も変更しました
for svr in `cat ~/srv.lst`; do
より成熟したものへ
while read -r srv; do
...
done < ~/src.lst
(あなたがしたように a をループすることは、非常に悪いbashの習慣と考えられcat
ています)。[[ -n "$srv" ]]
空行を無視するには、ガードを含める必要がありました。コメントを処理したい場合は、ここにもっと洗練されたものを追加できます...
ファイルがハイフンで始まる場合に備えて、にも追加--
しました。それは混乱します(それはオプションだと思います)。これは、非常に優れたシェル プラクティスと見なされます。scp
$locfile
scp
あなたがproduction environmentに言及しているように、私はそうすると思いました。(本番環境で使用されているスクリプトを見るのが怖いことがよくあります)。
実際、問題は[...]
as に安全に含めることができるため、ここでは必要ありませんcase
。
#!/bin/bash
#This script distributes file/folders to all POP servers within the production environment.
echo "Are you willing to transfer a file or a directory? [Answer: file/dir]"
read -r answer
echo "Please enter a file name or a full path to the files/directories you want to distribute"
read -r locfile
echo "Please enter the destination path"
read -r destfile
case "$answer" in
"")
true
# Do whatever you like here
;;
file)
while read -r srv; do
[[ -n "$srv" ]] || continue
echo "$srv:"
/usr/bin/scp -- "$locfile" "$srv:$destfile"
done < ~/srv.lst
;;
dir)
while read -r srv; do
[[ -n "$srv" ]] || continue
echo "$srv:"
/usr/bin/scp -r -- "$locfile" "$srv:$destfile"
done < ~/srv.lst
;;
*)
echo "Please check your input"
;;
esac
また、あなたのような「対話型」スクリプトは悪い習慣と見なされます (これは、古いファミリー コンピューターの古い BASIC プログラムを思い起こさせますか?)。代わりに、スクリプトに引数を使用することを検討する必要があります (演習は読者に任せます)。
ディレクトリかどうかをテストすることで、ディレクトリとファイルの問題を完全に取り除くことができます$locfile
。(verbose) オプションを使用して、echo
どのファイルがscp
ingであるかを示す を取り除きます。-v
#!/bin/bash
#This script distributes file/folders to all POP servers within the production environment.
read -r -p "Please enter a file name or a full path to the files/directories you want to distribute" locfile
read -r -p "Please enter the destination path" destfile
ropt=""
if [[ -d "$locfile" ]]; then
ropt='r'
fi
while read -r srv; do
[[ -n "$srv" ]] && /usr/bin/scp -v$ropt -- "$locfile" "$srv:$destfile"
done < ~/srv.lst
実際、あなたのスクリプトが何をするかを見れば見るほど、ユーザーが端末に入力する方がはるかに速いと思います。
$ while read -r srv; do [[ -n "$srv" ]] && /usr/bin/scp -v "myfile" "$srv:mydestfile"; done < ~/srv.lst
(彼女はタブでファイル名補完を使用できるため)、スクリプトを呼び出すのではなく.
お役に立てれば!