
Estou trabalhando em um script bash e preciso implementar "opções". Como posso fazer isso com o bash?
meu objetivo é executar o script da seguinte maneira:
/myscript.sh -d "/var/log/" -c "test"
o que eu tentei:
while shift; do
case $1 in
-d)
shift&&DIR="$1"||die
;;
-c)
shift&&COMMAND="$1"||die
;;
esac
done
echo "$DIR"
echo "$COMMAND"
Responder1
Para ampliar a resposta do @choroba, aqui vai um exemplo de como usar getopts
:
# parse the flag options (and their arguments)
while getopts c:d: OPT; do
case "$OPT" in
d)
DIR="$OPTARG" ;;
c)
COMMAND="$OPTARG" ;;
[?])
# got invalid option
echo "Usage: $0 [-d directory] [-c command]" >&2
exit 1 ;;
esac
done
# get rid of the just-finished flag arguments
shift $(($OPTIND-1))
Observe que depois de desativar os argumentos do sinalizador, quaisquer argumentos "regulares" permanecerão. Então, nesse ponto, você pode lidar com eles (por exemplo ... for arg in "$@"; do ...
, ) ou, se o seu script não os aceitar, apenas reclame se obtiver algum ( if [ $# -gt 0 ]; then echo "Usage ...
).
Responder2
Seu erro é que você está mudando no topo do loop, lançando o primeiro argumento antes de examiná-lo. Isso é o que acho que você provavelmente quis dizer:
#!/bin/bash
while (( "$#" )); do
case $1 in
-d)
shift&&DIR="$1"||die
;;
-c)
shift&&COMMAND="$1"||die
;;
esac
shift
done
echo "$DIR"
echo "$COMMAND"
Responder3
Como o choroba já disse,obter opçõesé uma abordagem melhor.
No seu caso, você poderia usar:
getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG
para conseguir o que você está tentando fazer com o loop while.
A string c:d:
especifica as opções possíveis. Os dois pontos significam que a opção requer um argumento.
O problema da sua abordagem é que você liga shift
antes de analisar o primeiro argumento, descartando-o no processo.
Para corrigir isso, altere o loop while para o seguinte:
while true; do
case $1 in
-d)
shift&&DIR="$1"||die
;;
-c)
shift&&COMMAND="$1"||die
;;
esac
shift || break
done
Responder4
A abordagem usual é usar getopts
.