我知道,我可以輕鬆地獲得定位參數,這樣在bash:如何獲得的參數與國旗在bash腳本
$0
或$1
我希望能夠使用標誌選項像這樣指定什麼每個參數用於:
mysql -u user -h host
什麼是讓-u param
值和標誌,而不是由位置-h param
價值的最佳方式是什麼?
我知道,我可以輕鬆地獲得定位參數,這樣在bash:如何獲得的參數與國旗在bash腳本
$0
或$1
我希望能夠使用標誌選項像這樣指定什麼每個參數用於:
mysql -u user -h host
什麼是讓-u param
值和標誌,而不是由位置-h param
價值的最佳方式是什麼?
這是成語我通常使用:
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
關鍵點是:
$#
是參數getopt的是你的朋友..一個簡單的例子:
function f() {
TEMP=`getopt --long -o "u:h:" "[email protected]"`
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
應該有你的/ usr/bin目錄的各種例子。
在Ubuntu機器上至少可以在目錄'/ usr/share/doc/util-linux/examples'中找到一個更廣泛的例子。 –
此示例使用bash的內置getopts
命令是從Google Shell Style Guide:
verbose='false'
aflag=''
bflag=''
files=''
while getopts 'abf:v' flag; do
case "${flag}" in
a) aflag='true' ;;
b) bflag='true' ;;
f) files="${OPTARG}" ;;
v) verbose='true' ;;
*) error "Unexpected option ${flag}" ;;
esac
done
注:如果一個字符後面跟一個冒號(如f:
),該選項預計將有一個說法。
實例:./script -v -a -b -f filename
使用getopts的具有優於接受的回答幾個優點:
-a -b -c
→-abc
)然而,一個很大的缺點是,它不支持長選項中,只有單字符選項。
另一種方法是使用類似下面的例子中,這將允許您使用長--image或短-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";
# [email protected] here represents all arguments passed in
for i in "[email protected]"
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";
我認爲服務器可以作爲您想要實現的簡單示例。沒有必要使用外部工具。 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";
}
這將允許您使用國旗所以無論哪個命令你正在傳遞的參數,你會得到正確的行爲。
例子:
DOSOMETHING -last "Adios" -first "Hola"
輸出:
First argument : Hola
Last argument : Adios
可以將此功能添加到您的個人資料或把它放在一個腳本里面。
謝謝!
編輯: 保存此爲AA文件,然後執行它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";
我喜歡羅伯特·麥克馬漢的回答這裏最好的,因爲它似乎最容易使之成爲共享包括文件中的任何腳本來使用。但它似乎有一個瑕疵與行if [[ -n ${variables[$argument_label]} ]]
投擲消息,「變量:壞數組下標」。我沒有代表評論,我懷疑這是正確的'修復',但包裝在if [[ -n $argument_label ]] ; then
清理它。
下面是我最終得到的代碼,如果你知道更好的方法,請給Robert的答案添加評論。
包含文件 「flags-declares.sh」
# declaring a couple of associative arrays
declare -A arguments=();
declare -A variables=();
# declaring an index integer
declare -i index=1;
包含文件 「flags-arguments.sh」
# [email protected] here represents all arguments passed in
for i in "[email protected]"
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;
你 「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";
它可能在http://unix.stackexchange.com/上查詢/檢查是個好主意,以及 – MRR0GERS
谷歌的「bash getopts」 - 很多教程。 –
@ glenn-jackman:我現在肯定會google了一下,我知道這個名字。關於谷歌的事情是 - 提出一個問題 - 你應該已經知道50%的答案。 – Stann