我想操作用户输入后从数组中选择的变量的扩展值。这就是我的意思:
$ ./myscript.sh url2
#!/bin/bash
array=(Sigil wp2epub csskit)
Sigil = "https://github.com/Sigil-Ebook/Sigil.git"
csskit = "https://github.com/mattharrison/epub-css-starter-kit.git"
wp2epub = "https://github.com/mrallen1/wp2md.git"
if [ -z $1 ]; then
echo "This script needs at least one parameter!"
exit 1
fi
if [ $1 = Sigil ]; then
ans=$Sigil # expanded
elif [ $1 = csskit ]; then
ans=$csskit # expanded
elif [ $1 = wp2epub ]; then
ans=$wp2epub # expanded
else
echo "Please inform one of \
Sigil, csskit or wp2epub!"
fi
git clone $ans
解释:
该脚本检查用户输入 ($1),将其与可能变量的数组进行比较,如果找到,它将检索该变量的扩展值作为答案,然后使用扩展值(而不是变量名称)。
我已经尝试了好几天了,但我有限的 bash 脚本编写能力还不够......
提前致谢。
根据 @terdon 请求:我希望用户告知数组中变量的名称,这将是人类友好的。
这些变量实际上是需要从github(git克隆)获取然后重新编译和重新安装的包的名称。
实际用法是:
$ ./update.sh Sigil # Sigil is one of the variables
答案1
使用关联数组:
#!/bin/bash
declare -A url
url=( [url1]="http://www.google.com"
[url2]="http://www.yahoo.com"
[url3]="http://www.bing.com"
)
if [[ -z $1 ]] ; then
echo "This script needs at least one parameter!"
exit 1
elif [[ -z ${url[$1]} ]] ; then
echo 'Unknown option'
exit 1
fi
echo "Let's search ${url[$1]}."
答案2
在您提供的脚本中:$1
包含选项的名称,并且 an$array
包含选项的值。要根据您的请求在扩展的变量中获取结果$ans
,有几个选项:
评估
eval:将 $1 展开为Sigil
例如,并赋值$Sigil
给 ans:
eval ans\=\"\$\{"$1"\}\"
然而,这假设这$1
是一个变量的单字标签。如果输入有其他内容,则可能会被 eval 评估。更强大的 eval 解决方案是使用${array[i]}
替代方案,因为数组的内容由脚本控制。
间接
bash 中一个相近的惯用语是${!1}
.这就是获取 var 所指向的值$1
,这正是我们所需要的。再次,更稳健地使用(一旦找到${array[i]}
匹配:$array[i]
a="array[i]"; ans="${!a}"
关联数组
但是,如果我们对数组键和数组值使用关联数组,则所有 eval 和间接寻址问题都可以避免。
然后很容易找到正确的值,如果数组有值,那么它就是有效值。如果数组中没有某个键的值,则该键无效。
基于这个概念的完整脚本可能如下所示:
#!/bin/bash
[ $# -lt 1 ] && { echo "This script needs at least one parameter!"; exit 1; }
declare -A a
a=(
[Sigil]="https://github.com/Sigil-Ebook/Sigil.git"
[wp2epub]="https://github.com/mattharrison/epub-css-starter-kit.git"
[csskit]="https://github.com/mrallen1/wp2md.git"
)
### Process an error while informing of options.
for val in "${!a[@]}"
do d=$d${d:+", "}$last
last=$val
done
d="Please inform one of $d or $last"
SayError(){ echo "$d" >&2; exit 1; }
### Process a valid command execution.
ExecCmd(){ git clone "$ans"; }
### Process all arguments of script.
for arg
do unset ans ### unset result variable.
printf -v ans '%s' "${a[$arg]}" ### Assign result to "$ans"
${ans:+:} SayError ### If "$ans" is empty, process error.
${ans:+false} || ExecCmd ### With valid "$ans" execute command.
done
可以更改函数 SayError 以消除exit 1
,脚本仍将处理所有参数,并对无效值发出警告。
答案3
arr=($url1 $url2 $url3)
for i in ${arr[@]}; do
if [[ $i == $1 ]] ;then
ans=$i
break
fi
done