Bash에서 플래그가 있는 인수를 가져오는 방법
bash에서 다음과 같은 매개변수를 쉽게 얻을 수 있다는 것을 알고 있습니다.
$0
또는$1
다음과 같은 플래그 옵션을 사용하여 각 매개 변수에 대해 지정할 수 있습니다.
mysql -u user -h host
가장 좋은 방법은 무엇입니까?-u param
및 치와-h param
위치가 아닌 플래그별로 값을 지정할 수 있습니까?
이 예제는 Bash의 내장 명령을 사용하며 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
콜론: 콜론)이 오는 경우:f:
됩니다.), 에 포함되어 있습니다.
사용 예: ./script -v -a -b -f filename
getopts를 사용하는 것은 허용된 답변보다 몇 가지 이점이 있습니다.
- 반면 조건은 훨씬 더 읽기 쉽고 허용된 옵션이 무엇인지 보여줍니다.
- 클리너 코드, 매개 변수 수 및 이동을 계산하지 않음
- 예옵션에수있습다니가할입)에 가입할 수 있습니다.
-a -b -c
→-abc
)
하지만 긴 옵션은 지원하지 않고 한 글자 옵션만 지원한다는 것이 큰 단점입니다.
제가 주로 사용하는 관용구는 다음과 같습니다.
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
요점은 다음과 같습니다.
$#
수의인입니다의 입니다.- 루프가 제공된 모든 인수를 확인하는 동안, case 문 안의 값에 일치합니다.
- 시프트는 첫 번째 것을 제거합니다.사례 문 안에서 여러 번 이동하여 여러 값을 취할 수 있습니다.
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
/usr/bin 디렉터리에는 다양한 예제가 있어야 합니다.
저는 시작되지 않은 것에 대한 간단한 TLDR:; 예를 제안합니다.
greeter라는 bash 스크립트를 생성합니다.쉬
#!/bin/bash
while getopts "n:" arg; do
case $arg in
n) Name=$OPTARG;;
esac
done
echo "Hello $Name!"
인 매개 변수 " " " " " " " " 를 할 수 .-n
스크립트를 실행할 때 사용합니다.
다음과 같이 스크립트를 실행합니다.
$ bash greeter.sh -n 'Bob'
산출량
$ Hello Bob!
메모들
여러 매개 변수를 사용하려는 경우:
- 확장하다, 하다, 확대하다
while getops "n:" arg: do
같더 많매변수로와 같은 가 더 많은while getops "n:o:p:" arg: do
- 추가 변수 할당으로 케이스 스위치를 확장합니다.를 들어, 를들어와 같은.
o) Option=$OPTARG
그리고.p) Parameter=$OPTARG
스크립트를 실행 파일로 만드는 방법
chmod u+x greeter.sh
저는 이것이 당신이 성취하고자 하는 것에 대한 더 간단한 예가 될 것이라고 생각합니다.외부 도구를 사용할 필요가 없습니다.내장된 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
프로필에 이 기능을 추가하거나 스크립트 내부에 넣을 수 있습니다.
감사합니다!
편집 : 파일로 저장한 후 다음과 같이 실행합니다.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";
또 다른 대안은 긴 --image 또는 short-i 태그를 사용할 수 있고 컴파일된 -i="instra.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";
저는 여기서 로버트 맥마한의 답변이 가장 마음에 듭니다. 왜냐하면 당신의 스크립트에서 사용할 수 있는 공유 가능한 포함 파일로 만드는 것이 가장 쉬운 것 같기 때문입니다.하지만 라인에 결함이 있는 것 같습니다.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;
"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;
당신의 "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";
#!/bin/bash
if getopts "n:" arg; then
echo "Welcome $OPTARG"
fi
sample.sh 으로 저장하고 실행해 보십시오.
sh sample.sh -n John
당신의 터미널에서.
Python argparse에 익숙하고 bash 인수를 구문 분석하기 위해 python을 불러도 괜찮으시다면 argparse-parse https://github.com/nhoffman/argparse-bash 라는 매우 유용하고 사용하기 쉬운 코드가 있습니다.
예는 그들의 예에서 따온 것입니다.sh 스크립트:
#!/bin/bash
source $(dirname $0)/argparse.bash || exit 1
argparse "$@" <<EOF || exit 1
parser.add_argument('infile')
parser.add_argument('outfile')
parser.add_argument('-a', '--the-answer', default=42, type=int,
help='Pick a number [default %(default)s]')
parser.add_argument('-d', '--do-the-thing', action='store_true',
default=False, help='store a boolean [default %(default)s]')
parser.add_argument('-m', '--multiple', nargs='+',
help='multiple values allowed')
EOF
echo required infile: "$INFILE"
echo required outfile: "$OUTFILE"
echo the answer: "$THE_ANSWER"
echo -n do the thing?
if [[ $DO_THE_THING ]]; then
echo " yes, do it"
else
echo " no, do not do it"
fi
echo -n "arg with multiple values: "
for a in "${MULTIPLE[@]}"; do
echo -n "[$a] "
done
echo
여러 플래그가 있는 getopts를 사용하는 데 어려움이 있어서 이 코드를 작성했습니다.모달 변수를 사용하여 플래그를 탐지하고 이러한 플래그를 사용하여 변수에 인수를 할당합니다.
플래그에 인수가 없어야 하는 경우 CURRENTFLAG 설정 이외의 작업을 수행할 수 있습니다.
for MYFIELD in "$@"; do
CHECKFIRST=`echo $MYFIELD | cut -c1`
if [ "$CHECKFIRST" == "-" ]; then
mode="flag"
else
mode="arg"
fi
if [ "$mode" == "flag" ]; then
case $MYFIELD in
-a)
CURRENTFLAG="VARIABLE_A"
;;
-b)
CURRENTFLAG="VARIABLE_B"
;;
-c)
CURRENTFLAG="VARIABLE_C"
;;
esac
elif [ "$mode" == "arg" ]; then
case $CURRENTFLAG in
VARIABLE_A)
VARIABLE_A="$MYFIELD"
;;
VARIABLE_B)
VARIABLE_B="$MYFIELD"
;;
VARIABLE_C)
VARIABLE_C="$MYFIELD"
;;
esac
fi
done
이것이 제 해결책입니다.저는 하이픈 없이, 하나의 하이픈으로, 그리고 하나의 하이픈으로, 그리고 하나와 두 개의 하이픈으로 매개 변수/값 할당으로 부울 플래그를 처리할 수 있기를 원했습니다.
# Handle multiple types of arguments and prints some variables
#
# Boolean flags
# 1) No hyphen
# create Assigns `true` to the variable `CREATE`.
# Default is `CREATE_DEFAULT`.
# delete Assigns true to the variable `DELETE`.
# Default is `DELETE_DEFAULT`.
# 2) One hyphen
# a Assigns `true` to a. Default is `false`.
# b Assigns `true` to b. Default is `false`.
# 3) Two hyphens
# cats Assigns `true` to `cats`. By default is not set.
# dogs Assigns `true` to `cats`. By default is not set.
#
# Parameter - Value
# 1) One hyphen
# c Assign any value you want
# d Assign any value you want
#
# 2) Two hyphens
# ... Anything really, whatever two-hyphen argument is given that is not
# defined as flag, will be defined with the next argument after it.
#
# Example:
# ./parser_example.sh delete -a -c VA_1 --cats --dir /path/to/dir
parser() {
# Define arguments with one hyphen that are boolean flags
HYPHEN_FLAGS="a b"
# Define arguments with two hyphens that are boolean flags
DHYPHEN_FLAGS="cats dogs"
# Iterate over all the arguments
while [ $# -gt 0 ]; do
# Handle the arguments with no hyphen
if [[ $1 != "-"* ]]; then
echo "Argument with no hyphen!"
echo $1
# Assign true to argument $1
declare $1=true
# Shift arguments by one to the left
shift
# Handle the arguments with one hyphen
elif [[ $1 == "-"[A-Za-z0-9]* ]]; then
# Handle the flags
if [[ $HYPHEN_FLAGS == *"${1/-/}"* ]]; then
echo "Argument with one hyphen flag!"
echo $1
# Remove the hyphen from $1
local param="${1/-/}"
# Assign true to $param
declare $param=true
# Shift by one
shift
# Handle the parameter-value cases
else
echo "Argument with one hyphen value!"
echo $1 $2
# Remove the hyphen from $1
local param="${1/-/}"
# Assign argument $2 to $param
declare $param="$2"
# Shift by two
shift 2
fi
# Handle the arguments with two hyphens
elif [[ $1 == "--"[A-Za-z0-9]* ]]; then
# NOTE: For double hyphen I am using `declare -g $param`.
# This is the case because I am assuming that's going to be
# the final name of the variable
echo "Argument with two hypens!"
# Handle the flags
if [[ $DHYPHEN_FLAGS == *"${1/--/}"* ]]; then
echo $1 true
# Remove the hyphens from $1
local param="${1/--/}"
# Assign argument $2 to $param
declare -g $param=true
# Shift by two
shift
# Handle the parameter-value cases
else
echo $1 $2
# Remove the hyphens from $1
local param="${1/--/}"
# Assign argument $2 to $param
declare -g $param="$2"
# Shift by two
shift 2
fi
fi
done
# Default value for arguments with no hypheb
CREATE=${create:-'CREATE_DEFAULT'}
DELETE=${delete:-'DELETE_DEFAULT'}
# Default value for arguments with one hypen flag
VAR1=${a:-false}
VAR2=${b:-false}
# Default value for arguments with value
# NOTE1: This is just for illustration in one line. We can well create
# another function to handle this. Here I am handling the cases where
# we have a full named argument and a contraction of it.
# For example `--arg1` can be also set with `-c`.
# NOTE2: What we are doing here is to check if $arg is defined. If not,
# check if $c was defined. If not, assign the default value "VD_"
VAR3=$(if [[ $arg1 ]]; then echo $arg1; else echo ${c:-"VD_1"}; fi)
VAR4=$(if [[ $arg2 ]]; then echo $arg2; else echo ${d:-"VD_2"}; fi)
}
# Pass all the arguments given to the script to the parser function
parser "$@"
echo $CREATE $DELETE $VAR1 $VAR2 $VAR3 $VAR4 $cats $dir
일부 참조
- 주요 절차는 여기에 있습니다.
- 함수에 모든 인수를 전달하는 방법에 대한 자세한 내용은 다음과 같습니다.
- 기본값에 대한 자세한 내용은 여기를 참조하십시오.
- 에 대한 추가 정보
declare
하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 나다$ bash -c "help declare"
. - 에 대한 추가 정보
shift
하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 나다$ bash -c "help shift"
.
언급URL : https://stackoverflow.com/questions/7069682/how-to-get-arguments-with-flags-in-bash
'programing' 카테고리의 다른 글
WPF 창에서 닫기 단추를 숨기는 방법은 무엇입니까? (0) | 2023.05.23 |
---|---|
mongoDB 레코드 일괄 찾기(mongoid 루비 어댑터 사용) (0) | 2023.05.23 |
VBA를 사용하여 폴더의 파일을 순환하시겠습니까? (0) | 2023.05.23 |
Postgre에 사용자 정의 유형이 이미 있는지 확인합니다.SQL (0) | 2023.05.23 |
로컬 리포지토리 git을 삭제하려면 어떻게 해야 합니까? (0) | 2023.05.23 |