我知道我可以轻松地在bash中获取这样的定位参数:
$0 要么 $1
我希望能够使用这样的标志选项来指定使用每个参数的内容:
mysql -u user -h host
Run Code Online (Sandbox Code Playgroud)
通过国旗而不是按位置获得-u param价值和-h param价值的最佳方法是什么?
Den*_*nis 390
此示例使用Bash的内置getopts命令,来自Google Shell Style Guide:
a_flag=''
b_flag=''
files=''
verbose='false'
print_usage() {
printf "Usage: ..."
}
while getopts 'abf:v' flag; do
case "${flag}" in
a) a_flag='true' ;;
b) b_flag='true' ;;
f) files="${OPTARG}" ;;
v) verbose='true' ;;
*) print_usage
exit 1 ;;
esac
done
Run Code Online (Sandbox Code Playgroud)
注意:如果一个字符后面跟一个冒号(例如f:),那么该选项应该有一个参数.
用法示例: ./script -v -a -b -f filename
使用getopts比接受的答案有几个优点:
-a -b -c→ -abc)但是,一个很大的缺点是它不支持长选项,只支持单字符选项.
Fle*_*exo 267
这是我经常使用的习语:
while test $# -gt 0; do
case "$1" in
-h|--help)
echo "$package - attempt to capture frames"
echo " "
echo "$package [options] application [arguments]"
echo " "
echo "options:"
echo "-h, --help show brief help"
echo "-a, --action=ACTION specify an action to use"
echo "-o, --output-dir=DIR specify a directory to store output in"
exit 0
;;
-a)
shift
if test $# -gt 0; then
export PROCESS=$1
else
echo "no process specified"
exit 1
fi
shift
;;
--action*)
export PROCESS=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
-o)
shift
if test $# -gt 0; then
export OUTPUT=$1
else
echo "no output dir specified"
exit 1
fi
shift
;;
--output-dir*)
export OUTPUT=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
*)
break
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
要点是:
$# 是参数的数量Shi*_*zmo 46
getopt是你的朋友..一个简单的例子:
function f () {
TEMP=`getopt --long -o "u:h:" "$@"`
eval set -- "$TEMP"
while true ; do
case "$1" in
-u )
user=$2
shift 2
;;
-h )
host=$2
shift 2
;;
*)
break
;;
esac
done;
echo "user = $user, host = $host"
}
f -u myself -h some_host
Run Code Online (Sandbox Code Playgroud)
/ usr/bin目录中应该有各种示例.
pij*_*olu 13
我提出了一个简单的 TLDR:; 未启动的示例。
创建一个名为greeter.sh的bash脚本
#!/bin/bash
while getopts "n:" arg; do
case $arg in
n) Name=$OPTARG;;
esac
done
echo "Hello $Name!"
Run Code Online (Sandbox Code Playgroud)
然后,您可以-n在执行脚本时传递一个可选参数。
执行脚本如下:
$ bash greeter.sh -n 'Bob'
Run Code Online (Sandbox Code Playgroud)
输出
$ Hello Bob!
Run Code Online (Sandbox Code Playgroud)
笔记
如果您想使用多个参数:
while getops "n:" arg: do更多参数,例如
while getops "n:o:p:" arg: doo) Option=$OPTARG和p) Parameter=$OPTARG要使脚本可执行:
chmod u+x greeter.sh
Run Code Online (Sandbox Code Playgroud)
我认为这可以作为您想要实现的更简单的例子.无需使用外部工具.内置工具的Bash可以为您完成工作.
function DOSOMETHING {
while test $# -gt 0; do
case "$1" in
-first)
shift
first_argument=$1
shift
;;
-last)
shift
last_argument=$1
shift
;;
*)
echo "$1 is not a recognized flag!"
return 1;
;;
esac
done
echo "First argument : $first_argument";
echo "Last argument : $last_argument";
}
Run Code Online (Sandbox Code Playgroud)
这将允许您使用标志,因此无论您传递参数的顺序,您都将获得正确的行为.
示例:
DOSOMETHING -last "Adios" -first "Hola"
Run Code Online (Sandbox Code Playgroud)
输出:
First argument : Hola
Last argument : Adios
Run Code Online (Sandbox Code Playgroud)
您可以将此功能添加到您的配置文件或将其放在脚本中.
谢谢!
编辑:将其另存为文件,然后执行 yourfile.sh -last "Adios" -first "Hola"
#!/bin/bash
while test $# -gt 0; do
case "$1" in
-first)
shift
first_argument=$1
shift
;;
-last)
shift
last_argument=$1
shift
;;
*)
echo "$1 is not a recognized flag!"
return 1;
;;
esac
done
echo "First argument : $first_argument";
echo "Last argument : $last_argument";
Run Code Online (Sandbox Code Playgroud)
小智 6
我最喜欢罗伯特·麦克马汉的答案,因为它似乎最容易制作成可共享的包含文件以供任何脚本使用。但抛出消息“变量:错误的数组下标”的行似乎有一个缺陷if [[ -n ${variables[$argument_label]} ]]。我没有代表发表评论,我怀疑这是否是正确的“修复”,但将其包含if在内if [[ -n $argument_label ]] ; then可以清理它。
这是我最终得到的代码,如果您知道更好的方法,请在罗伯特的答案中添加评论。
包含文件“flags-declares.sh”
# declaring a couple of associative arrays
declare -A arguments=();
declare -A variables=();
# declaring an index integer
declare -i index=1;
Run Code Online (Sandbox Code Playgroud)
包含文件“flags-arguments.sh”
# $@ here represents all arguments passed in
for i in "$@"
do
arguments[$index]=$i;
prev_index="$(expr $index - 1)";
# this if block does something akin to "where $i contains ="
# "%=*" here strips out everything from the = to the end of the argument leaving only the label
if [[ $i == *"="* ]]
then argument_label=${i%=*}
else argument_label=${arguments[$prev_index]}
fi
if [[ -n $argument_label ]] ; then
# this if block only evaluates to true if the argument label exists in the variables array
if [[ -n ${variables[$argument_label]} ]] ; then
# dynamically creating variables names using declare
# "#$argument_label=" here strips out the label leaving only the value
if [[ $i == *"="* ]]
then declare ${variables[$argument_label]}=${i#$argument_label=}
else declare ${variables[$argument_label]}=${arguments[$index]}
fi
fi
fi
index=index+1;
done;
Run Code Online (Sandbox Code Playgroud)
你的“script.sh”
. bin/includes/flags-declares.sh
# any variables you want to use here
# on the left left side is argument label or key (entered at the command line along with it's value)
# on the right side is the variable name the value of these arguments should be mapped to.
# (the examples above show how these are being passed into this script)
variables["-gu"]="git_user";
variables["--git-user"]="git_user";
variables["-gb"]="git_branch";
variables["--git-branch"]="git_branch";
variables["-dbr"]="db_fqdn";
variables["--db-redirect"]="db_fqdn";
variables["-e"]="environment";
variables["--environment"]="environment";
. bin/includes/flags-arguments.sh
# then you could simply use the variables like so:
echo "$git_user";
echo "$git_branch";
echo "$db_fqdn";
echo "$environment";
Run Code Online (Sandbox Code Playgroud)
另一个替代方法是使用类似下面的示例,它允许您使用long --image或short -i标记,还允许编译-i ="example.jpg"或单独的-i example.jpg传入参数的方法.
# declaring a couple of associative arrays
declare -A arguments=();
declare -A variables=();
# declaring an index integer
declare -i index=1;
# any variables you want to use here
# on the left left side is argument label or key (entered at the command line along with it's value)
# on the right side is the variable name the value of these arguments should be mapped to.
# (the examples above show how these are being passed into this script)
variables["-gu"]="git_user";
variables["--git-user"]="git_user";
variables["-gb"]="git_branch";
variables["--git-branch"]="git_branch";
variables["-dbr"]="db_fqdn";
variables["--db-redirect"]="db_fqdn";
variables["-e"]="environment";
variables["--environment"]="environment";
# $@ here represents all arguments passed in
for i in "$@"
do
arguments[$index]=$i;
prev_index="$(expr $index - 1)";
# this if block does something akin to "where $i contains ="
# "%=*" here strips out everything from the = to the end of the argument leaving only the label
if [[ $i == *"="* ]]
then argument_label=${i%=*}
else argument_label=${arguments[$prev_index]}
fi
# this if block only evaluates to true if the argument label exists in the variables array
if [[ -n ${variables[$argument_label]} ]]
then
# dynamically creating variables names using declare
# "#$argument_label=" here strips out the label leaving only the value
if [[ $i == *"="* ]]
then declare ${variables[$argument_label]}=${i#$argument_label=}
else declare ${variables[$argument_label]}=${arguments[$index]}
fi
fi
index=index+1;
done;
# then you could simply use the variables like so:
echo "$git_user";
Run Code Online (Sandbox Code Playgroud)
#!/bin/bash
if getopts "n:" arg; then
echo "Welcome $OPTARG"
fi
Run Code Online (Sandbox Code Playgroud)
将其保存为sample.sh并尝试运行
sh sample.sh -n John
Run Code Online (Sandbox Code Playgroud)
在您的终端中。
| 归档时间: |
|
| 查看次数: |
224547 次 |
| 最近记录: |