我使用 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
发生了什么变化?更多引用(当文件名包含空格时,您的脚本迟早会中断)并使用 of[[...]]
而不是 deprecated 和不太健壮(在 bash 中)[...]
。我还使用read
了该-r
选项(因为不允许反斜杠转义任何字符)。我也改了
for svr in `cat ~/srv.lst`; do
进入更成熟的
while read -r srv; do
...
done < ~/src.lst
(像你做的那样循环 a真的被认为是非常cat
糟糕的 bash 做法)。我必须包括一个守卫[[ -n "$srv" ]]
来忽略空行。如果要处理评论,您可以在此处添加更复杂的内容...
我还添加--
了scp
,以防文件$locfile
以连字符开头。那会令人困惑scp
(它会认为这是一种选择)。这被认为是非常好的 shell 实践。
正如您提到的生产环境,我想我会这样做。(我经常害怕看到生产中使用的脚本)。
实际上,您的问题是关于[...]
这里不需要的,因为您可以安全地将其包含在case
as 中:
#!/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
通过测试是否是 dir ,您可以完全摆脱 dir vs file 的事情。并通过使用(verbose) 选项摆脱echo
告诉它正在执行哪个文件的那个:scp
-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
(因为她将能够使用制表符完成文件名),而不是调用您的脚本。
希望这可以帮助!