我正在编写一个脚本来从源代码构建软件,并且有一个--platforms
选项。我想允许用户选择多个项目,但我不知道如何防止他们犯错。
例子:
read -p "For what platforms do you wish to build [mac/win/linux32/linux64/all] ? "
if [[ -n "`echo $REPLY | grep 'win\|mac\|linux32\|linux64\|all`" ]] ; then
echo "ok"
else
echo "not ok"
fi
Run Code Online (Sandbox Code Playgroud)
如果用户回答linux32
,应该没问题(而且确实如此)
如果用户回答linux32,mac
,应该没问题(而且确实如此)
如果用户回答lulz
,则不应该(事实并非如此)
如果用户回答linux32,lulz
,则不应该(这是我的问题)
我想知道您是否知道一种方法可以让用户输入他们想要的任何内容,以逗号分隔,但前提是它是脚本提供的选项之一,所以在这种情况下linux32 linux64 mac win all
.
也许case
有一种方法可以允许多个输入,或者添加一个elif $REPLY contains anything else than what we want
. 另一个想法,可以awk
用吗?我无法弄清楚自己该怎么做。
read
可以将输入分解为单词并将结果存储在数组中。将IFS
变量设置为单词分隔符(它需要是单个字符,而不是字符串——如果 的值IFS
包含多个字符,那么每个字符都是一个单词分隔符)。
IFS=, read -a platforms
Run Code Online (Sandbox Code Playgroud)
然后根据支持的平台集检查数组的每个元素。
for p in "${platforms[@]}"; do
case "$p" in
win|mac|linux32|linux64) :;;
all) platforms=(win mac linux32 linux64);;
*) printf 1>&2 "Unsupported platform: %s\n" "$p"; return 2;;
esac
done
Run Code Online (Sandbox Code Playgroud)
您还可以一次性比较一组平台。如果您不想在检查代码中对支持的平台集进行硬编码,这会更方便。
supported_platforms=(win mac linux32 linux64)
IFS=, read -a platforms
bad_platform_names=($(comm -23 <(printf '%s\n' all "${platforms[@]}" | sort -u) \
<(printf '%s\n' "${supported_platforms[@]}" | sort -u)))
if [[ ${#bad_platform_names[@]} -ne 0 ]]; then
printf "Unsupported platform: %s\n" "${bad_platform_names[@]}"
exit 1
fi
if printf '%s\n' "${platforms[@]}" | grep -qx all; then
platforms=("${supported_platforms[@]}")
fi
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用select
内置函数一次提示一个平台。
¹当然,如果您愿意,您可以在纯 bash 中执行此操作。
尝试这个!
buildvar=0
read -p "For what platforms do you wish to build [mac/win/linux32/linux64/all] ? " input
IFS=',' read -a options <<< "$input"
for option in "${options[@]}"
do
case "$option" in
linux32)
buildcommand="linux32" && buildvar=1
;;
linux64)
[ $buildvar == 1 ] && buildcommand="$buildcommand",linux64 || buildcommand="linux64" && buildvar=1
;;
mac)
[ $buildvar == 1 ] && buildcommand="$buildcommand",mac || buildcommand="mac" && buildvar=1
;;
win)
[ $buildvar == 1 ] && buildcommand="$buildcommand",win || buildcommand="win" && buildvar=1
;;
all)
buildcommand="all" && buildvar=1
;;
*)
echo "'$option' was ignored."
;;
esac
done
[ $buildvar == "0" ] && echo "Incorrect input. Default build selected." && buildcommand="default"
echo "=> $buildcommand"
Run Code Online (Sandbox Code Playgroud)
这将提示输入逗号分隔的选项列表。然后,它将将此列表拆分为一个数组,并遍历各个元素,分别检查每个元素,然后将所有“好”元素合并到一个变量中。
read -p 'Enter a comma-separated list of platforms to build for [win/mac/linux32/linux64/all]: ' input
IFS=',' read -a options <<< "$input"
shopt -s extglob
for option in "${options[@]}"; do
case "$option" in
win|mac|linux@(32|64)|all)
buildcommand="${buildcommand:+$buildcommand,}$option"
buildvar=1;;
*)
printf 'Invalid option "%s" ignored.\n' "$option" >&2;;
esac
done
IFS=',' read -a options <<< "$buildcommand"
for option in "${options[@]}"; do
if [[ $option == 'all' ]]; then
buildcommand='all'
break
fi
done
if (( !buildvar )); then
echo 'Incorrect input. Default build selected.' >&2
buildcommand='default'
fi
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1490 次 |
最近记录: |