Vou me concentrar na linha de comando analisando aqui:
# defaults:
ision=0
vison=0
while getopts "iv" option; do
case "$option" in
i)
echo "interactive mode set"
ision=1 ;;
v)
echo "verbose mode"
vison=1 ;;
*)
exit 1 ;;
esac
done
shift $(( OPTIND - 1 ))
(( vison )) && echo 'This is a verbose message'
if (( ision )); then
# interactive code
fi
É muito mais fácil operar com ision
e vison
se eles forem inteiros. Então você pode apenas testar seu valor com (( vison ))
, como mostrado acima.
Você também obteve a string de opção de comando getopts
wrong. Tanto quanto eu posso dizer, nenhuma opção leva um argumento, o que significa que não deve haver nenhum dois pontos na string. Se uma opção receber um argumento, os dois pontos deverão vir depois, como em v:
.
Não use break
quando estiver analisando a linha de comando, isso interromperá a análise. Em vez disso, basta definir os sinalizadores e fazer o que você precisa fazer e deixar o loop continuar. Eu estou supondo que você pode ter alguma familiaridade com C onde um faz precisa break
de uma instrução case
(em switch
). Não é o mesmo aqui.
Não faça a saída durante a análise da linha de comando, exceto como um auxílio de depuração. Muitos utilitários têm sinalizadores que se anulam, por ex. -v
para o modo detalhado seguido por -q
para o modo "silencioso" e ter a saída do código "entrando no modo detalhado" seguido de "entrar no modo silencioso" é apenas barulhento.
A propósito, para fazer algo assim (lidar com opções mutuamente exclusivas), você poderia ter
case "$option" in
q)
quiet=1
verbose=0 ;;
v)
verbose=1
quiet=0 ;;
# etc.
Quando o usuário usa -qv
, quiet
será primeiro definido como 1 e verbose
será definido como 0 e, em seguida, os valores serão revertidos. Não deve haver nenhum erro relatado neste caso, pois você não sabe se a linha de comando foi montada manualmente ou por um script de chamada.
Inseri uma instrução exit 1
que será executada se uma opção de linha de comando desconhecida for fornecida. Isso pode ser bom, pois significa que o usuário cometeu um erro e pode ser perigoso confiar cegamente no que está na linha de comando a partir daí.
O shift
(para desativar as opções analisadas) deve ser feito como acima. Mudar $OPTIND - 2
mudaria muitas coisas da lista de argumentos.
Também aprimorei o recuo, o que facilita a leitura e, portanto, facilita a depuração e a manutenção.
Quanto ao resto do roteiro, não olhei muito de perto, mas noto muitas expansões de variáveis sem nome. Não faça isso, pois isso atrapalhará as coisas se você receber nomes de arquivos com espaços (ou outros caracteres em branco) neles.
Especialmente $@
precisa ser citado quando usado em, e. rotações. Isso impede que os argumentos de linha de comando sejam divididos em espaços em branco (o conteúdo de $IFS
seja mais preciso) e evita a globalização acidental de nomes de arquivos, se os nomes contiverem caracteres de padrão globbing.
Há também um bom número de declarações continue
. IMHO, estes devem ser eliminados, pois dificultam o acompanhamento do fluxo do código (especialmente quando o código não é indentado corretamente). Eles não estão errados em si mesmos, mas podem ser removidos se o código lidar adequadamente com as várias condições. Em pelo menos um caso, você tem um echo
diretamente após uma instrução continue
, o que significa que esse echo
nunca será acionado:
continue
echo "cant remove safe_rm_restore"