Gostaria de passar argumentos longos para o script, e referi este link . Criei este my_script:
#!/usr/bin/env bash
#
# Adapted from https://www.shellscript.sh/examples/getopt/
#
set -euo pipefail
user_type=unset
user_id=unset
country=unset
dev_env=unset
position_id=unset
usage(){
>&2 cat << EOF
Usage: $0]
[ -a | --user_type input
[ -b | --user_id input ]
[ -c | --country input ]
[ -d | --dev_env input ]
[ -e | --position_id input ]
EOF
exit 1
}
>&2 echo [$@] passed to script
args=$(getopt -a -o ha:b:c:d: --long help,user_type:,user_id:,country:,dev_env:,position_id: -- "$@")
if [[ $? -gt 0 ]]; then
usage
fi
>&2 echo getopt creates [${args}]
eval set -- ${args}
while :
do
case $1 in
-a | --user_type) user_type=$2 ; shift 2 ;;
-b | --user_id) user_id=$2 ; shift 2 ;;
-h | --help) usage ; shift ;;
-c | --country) country=$2 ; shift 2 ;;
-d | --dev_env) dev_env=$2 ; shift 2 ;;
-e | --position_id) position_id=$2 ; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;;
*) >&2 echo Unsupported option: $1
usage ;;
esac
done
if [[ $# -eq 0 ]]; then
usage
fi
>&2 echo "user_type : ${user_type}"
>&2 echo "user_id : ${user_id} "
>&2 echo "country : ${country}"
>&2 echo "dev_env : ${dev_env}"
>&2 echo "position_id : ${position_id}"
>&2 echo "$# parameter/s remaining: $@"
>&2 echo "Looping through remaining parameter/s:"
# set input field separator to keep quoted parameters together
# for example, "my input" will remain as one input
IFS=$'\n'
for param in $@; do
>&2 echo -e "\t${param}"
done
echo "user ${user_type} with user id ${user_id} has been created with position_id $position_id"
exit 0
e no terminal tentei executá-lo como:
bash test_bash --user_type abc --user_id a1b2 --country aud --dev_env uat --position_id aFWf
Estou recebendo apenas uma mensagem de ajuda como:
[--user_type abc --user_id a1b2 --country aud --dev_env uat --position_id aFWf] passed to script
getopt creates [ --user_type 'abc' --user_id 'a1b2' --country 'aus' --dev_env 'uat' --position_id 'aFWf' --]
Usage: test_bash]
[ -a | --user_type input
[ -b | --user_id input ]
[ -c | --country input ]
[ -d | --dev_env input ]
[ -e | --position_id input ]
Eu tentei atualizar/alterar algumas coisas como args=getopt com algumas outras opções. Mas os argumentos não estão sendo analisados pelo script. Agradeço sua ajuda antecipadamente. Obrigado.
Aqui está, uma versão funcional do seu código. Vou sair de vez em quando para tentar explicar por que mudei o que mudei
Eu prefiro inicializar variáveis para um valor vazio e, então, substituir o texto dentro das mensagens de erro, se necessário. Você
user_type=unset
poderia funcionar, definindo a variável para o texto,unset
mas isso impede testes simples mais tarde, comoif [ -z "$user_type ]; then echo "the variable user_type has no value"; fi
, e definitivamente quebra se o usuário forneceunset
como um valor literal:Não faz sentido usar
$@
porque (a) você não colocou aspas duplas e (b) você está escrevendo uma string em vez de uma série de valores. (Procure a diferença entre$*
,$@
, e"$@"
se você não seguir isso). Finalmente, eu dissegetopt
para reportar erros em nome do seu programa. A${0##*/}
construção escolhe o nome do programa para você:Não se esqueça das aspas duplas em torno de
$args
:As
shift
declarações (acima) comem os argumentos conforme são processados. Mas em um momento você quer imprimir os argumentos restantes, então não faz sentido fugir com um erro de uso se não houver mais nenhum. Código removido.Acima, removi a condição de erro em
case
porque ela já é tratada diretamente porgetopt
.Nesta próxima seção, variáveis como
$user_type
podem ser não definidas, então elas não terão valor. Aqui o${user_type:-<unset>}
exibe<unset>
se o valor é não definido/vazio:Coloque aspas duplas
"$@"
para que as palavras sejam tratadas como elementos únicos, mesmo que originalmente contenham espaços em branco:Finalmente, se o código estiver no arquivo
myscript
, não o execute comobash myscript
. Em vez disso, defina o arquivo para ser legível/executável (chmod a+rx myscript
) e apenas execute-o diretamente (./myscript
). A primeira linha informa ao sistema qual interpretador usar, então não há necessidade de especificarbash
explicitamente ao executá-lo.Exemplo:
Ok, vamos resolver essa questão. Desculpe pela resposta anterior, mesmo que correta, mas eu estava no trem e não tive chance de explicar bem minha solução.
Aqui está seu código editado para funcionar como esperado:
Aqui está o resultado:
Como eu disse na resposta anterior, a segunda declaração if está errada porque neste ponto não há mais argumentos, então
$#
corresponde a0
e o código sai com status 1 dausage
função. Mas verificando bem seu código, antes disso, também*) >&2 echo Unsupported option: $1
quebre seu código da mesma forma, na minha opinião porque no--
métodogetopt
. Seu código está cheio de maneiras de gerenciar os argumentos fornecidos e isso geralmente não é uma boa ideia. Minha sugestão é manter o código o mais limpo possível.Aqui está o que é realmente útil do seu código para atingir o mesmo resultado:
Aqui está o resultado: