页次: 1
求助:bash中如何提取命令行选项的辅助参数
主程序名称: emacs-locale
程序目标:
* 判断并提取 -gl, -l -v 这三个选项的辅助参数,并保存到三个对应的数组中。
数组定义为 ARRAY_GL, ARRAY_L, ARRAY_V示例如下:
./emacs-locale -gl zh_CN -v 24.3
./emacs-locale -l zh_CN -v 24.3
说明:
-gl 代表全局语言相关选项(Global Language);
-l 代表当前用户语言相关选项(Language);
-v 代表 Emacs 版本号 (Version);* 容错功能
** 每个选项后允许输入多个参数,如:
./emacs-locale -gl zh_CN -v 24.3 23.1
./emacs-locale -gl zh_CN zh_TW -v 24.3 23.1
** 如果同一选项提供多次输入,则合并有效参数,如:
./emacs-locale -gl zh_CN -v 24.3 23.1 -gl zh_TW
等效于:
./emacs-locale -gl zh_CN zh_TW -v 24.3 23.1
** 能自动过滤无辅助参数的无效选项,如
./emacs-locale -gl -gl zh_CN -v 24.3 23.1 -gl zh_TW
上面的 -gl 选项出现多次,需要过滤
* 说明
完整的程序还有更多功能,这里仅列待解决部分的代码
相关代码见2楼
调试时发现有时能正确提取参数,但有时出现异常.
运行环境:
Ubuntu 10.04.3 i386
GNU bash, version 4.1.5(1)-release
示例代码如下:
命令行
./emacs-locale -gl gl1 gl2 gl3 -v v10 v11 -l l1 l2 -l l2 -l l3 -gl gl2 -v v21 gl
输出如下(输出结果有误,-l 选项的参数未能正确提取)
----
ARRAY_GL = 'gl1 gl2 gl3'
ARRAY_L = ''
ARRAY_V = 'v10 v11'
有劳哪位高手指点一下,多谢!
离线
接 1 楼
程序代码
#! /bin/bash
## coding: utf-8
## translate Emacs/XEmacs menu to other languages
## updated by Careone <emacslocale@126.com>, 2013-10-04
VERSION='2.12'
# Usage: usage
# Print the usage.
usage () {
cat <<EOF
Usage: $0 [OPTION]
toggle $NAMEU menu to special language, for current user or global.
You also can translate $NAMEU menu to special language(s) if translate
scripts existed. Please run '$0 -d' for translate/develop options.
-V, --version print the version information and exit
-h, --help print this message and exit
Translate and develop related options
usage: $0 -l LANGUAGE -v VERSION
examples: $0 -l zh_CN -v 24.1
$0 -l zh_CN -v 24.1 24.2
$0 -l zh_CN zh_TW -v 24.1 24.2
-gl [LANGUAGE_1 LANGUAGE_2 ...] (root please!)
with -v, (Global) translate $NAMEU lisp/*/*.el files to special
version(s). If no VERSION given, try probe current $NAMEU version
installed instead.
-l [LANGUAGE_1 LANGUAGE_2 ...]
with -v, translate $NAMEU lisp/*/*.el files to special language(s)
-v [VERSION1 VERSION2 ...]
with -gl or -l, translate $NAMEU lisp/*/*.el files to special version(s). If
no VERSION given, try probe current $NAMEU version installed instead.
!!! NOTICE !!!
* option '-l':
translated .el files save to ~/$TRANSOF/usr/share/$NAMEL/... and
apply to current user only
* option '-gl': (root please!)
translated .el files save to /usr/share/$NAMEL/... and apply to ALL
USERS. If you just want to test your translations, please use option
'-l' instead!
EOF
}
###
# tag 2000
## PART 2: main
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
## todo -------------------------
-gl | -l | -v)
declare -a ARRAY_GL
declare -a ARRAY_L
declare -a ARRAY_V
declare -a ARG
## 2013-09-20
#ARGS="$@"
case "$1" in
-gl)
shift
unset ARG[@] #init array to null
ARG=( `echo -n "$@" | sed "s/ -/\n -/" | head -1` )
if [ "${#ARG[@]}" -ge 1 ];then
# if argument like "-gl -gl zh_CN", throw the first -gl
case "${ARG[0]}" in
--* | -*): ;;
*)
if [ "${#ARRAY_GL[@]}" -ge 1 ];then
ARRAY_GL=( "${ARRAY_GL[@]}" "${ARG[@]}" )
else ARRAY_GL=( "${ARG[@]}" )
fi
shift "${#ARG[@]}"
# echo "ARRAY_GL = '${ARRAY_GL[@]}'"
esac
fi
continue
;;
-l)
shift
unset ARG[@] #init array to null
ARG=`echo -n "$@" | sed "s/ -/\n -/" | head -1`
if [ "${#ARG[@]}" -ge 1 ];then
# if argument like "-l -l zh_CN", throw the first -l
case "${ARG[0]}" in
--* | -*): ;;
*)
if [ "${#ARG[@]}" -ge 1 ];then
if [ "${#ARRAY_L[@]}" -ge 1 ];then
ARRAY_L=( "${ARRAY_L[@]}" "${ARG[@]}" )
else ARRAY_L=( "${ARG[@]}" )
fi
shift "${#ARG[@]}"
fi
# echo "ARRAY_L = '${ARRAY_L[@]}'"
esac
fi
continue
;;
-v)
shift
unset ARG[@] #init array to null
ARG=`echo -n "$@" | sed "s/ -/\n -/" | head -1`
if [ "${#ARG[@]}" -ge 1 ];then
# if argument like "-v -v 24", throw the first -v
case "${ARG[0]}" in
--* | -*): ;;
*)
if [ "${#ARG[@]}" -ge 1 ];then
if [ "${#ARRAY_V[@]}" -ge 1 ];then
ARRAY_V=( "${ARRAY_V[@]}" "${ARG[@]}" )
else ARRAY_V=( "${ARG[@]}" )
fi
shift "${#ARG[@]}"
fi
# echo "ARRAY_V = '${ARRAY_V[@]}'"
esac
fi
continue
;;
-*):
shift; continue
;;
esac
# Case of "-gl | -l | -v)" end
;;
##--------------------------
-*)
echo "Unrecognized option \`$option'" 1>&2
#exit 1
;;
esac
done
# ,FUZZY
##--------------------------
echo
echo "----"
echo "ARRAY_GL = '${ARRAY_GL[@]}'"
echo "ARRAY_L = '${ARRAY_L[@]}'"
echo "ARRAY_V = '${ARRAY_V[@]}'"
exit 0;
#
# -gl gl1 gl2 gl3 -v v10 v11 -l l1 l2 -l l2 -l l3 -gl gl2 -v v21 gl
### output:
#----
# ARRAY_GL = 'gl1 gl2 gl3'
# ARRAY_L = ''
# ARRAY_V = 'v10 v11'
离线
真悲伤,用这种坑爹语法害我不能飞 getopts 内置……还真得踩着你的 for 走呢。
# tag 2000
## PART 2: main
# Check the arguments.
# 匈牙利命名法吃 * 啦。
ARRAY_GL=()
ARRAY_L=()
ARRAY_V=()
BUF=()
# misaka-pseudo:
# each ARG:
# -gl <list> => ARRAY_GL.append(list)
# -v <list> => ARRAY_V.append(list)
# -l <list> => ARRAY_L.append(list)
# list can be nil, but none of its elements may contain any of the opts above.
# pseudoStateGraphDone.
# 里面整个用 alias 配单引号包起来替代函数可能会速度快一点,但是高亮会废掉。
_opt_flush(){
# alias _opt_flush='
case "$_list_type" in
gl) ARRAY_GL+=("${BUF[@]}");;
l) ARRAY_L+=("${BUF[@]}");;
v) ARRAY_V+=("${BUF[@]}");;
"") return 0;;
*) echo What the fuck; return 2;;
esac
BUF=()
# ' # End _opt_flush Alias Expansion Def.
}
for opt; do case "$opt" in
-h|--help)
usage
exit 0;;
-d)
usage_devel
exit 0;;
-gl)
_opt_flush
_list_type=gl;;
-l)
_opt_flush
_list_type=l;;
-v)
_opt_flush
_list_type=v;;
-m)
_opt_flush
_list_type=''
echo "This is a magical example for other opts.";;
--)
_opt_flush
_list_type='';;
-*)
echo "What is $opt?";;
*)
BUF+=("$opt");;
esac
done
_opt_flush
declare -p ARRAY_{L,GL,V} BUF
输出这样:
# ./24195 -gl gl1 gl2 gl3 -v v10 v11 -l l1 l2 -l l2 -l l3 -gl gl2 -v v21 gl -- bb cc dd
declare -a ARRAY_L='([0]="l1" [1]="l2" [2]="l2" [3]="l3")'
declare -a ARRAY_GL='([0]="gl1" [1]="gl2" [2]="gl3" [3]="gl2")'
declare -a ARRAY_V='([0]="v10" [1]="v11" [2]="v21" [3]="gl")'
declare -a BUF='([0]="bb" [1]="cc" [2]="dd")'
# ./24195 aa bb cc
declare -a ARRAY_L='()'
declare -a ARRAY_GL='()'
declare -a ARRAY_V='()'
declare -a BUF='([0]="aa" [1]="bb" [2]="cc")'
看了看你的代码,瞻前顾后,想得太多。
最近编辑记录 Arthur2e5 (2015-09-15 04:17:02)
Crawler.
离线
[csslayer] ˊ_>ˋ 改改你原始命令行参数的方式改成和 getopt 兼容的不是更好
[csslayer] 用单个参数,只不过需要 quote 的形式,或者用逗号
[Arthur2e5] @csslayer 我懒得。
[csslayer] ˊ_>ˋ 我以为你是一开始发帖的……结果是回帖吗,回个 2013 年的贴……
[Arthur2e5] 欸 2013 的吗
+ 我去!
+ 这版块是有多冷才会 2013 的帖子在第一页
+ jginhaznhNZALIwlinwnheazLnjlxnhLAKAHDKH
什么,这是 2013 的帖子?!T*&@!(*&(*@!#*)#@!
Crawler.
离线
页次: 1