Múltiplos argumentos para script

2

Estou tentando configurar o script abaixo para receber entradas de vários argumentos na linha de comando. Eu estou usando o script para solicitar certs ssl de letsencrypt. O script atualmente leva um domínio de cada vez, mas eu gostaria de poder configurá-lo para aceitar vários argumentos de linha de comando para que eu possa usá-lo para solicitar certificados para domínios que tenham vários nomes alternativos (exemplo: domain. com e www.domain.com) Eu tentei alterar CERTNAME="${2}" para CERTNAME="$@" e CERTNAME=$(echo "${2}" | sed -n "s/.*'\([^']\+\)'.*//p") para CERTNAME=$(echo "$@" | sed -n "s/.*'\([^']\+\)'.*//p") , mas ele fica preso em echo "error: wrong CERTTYPE" . Eu corro o script como ./<script name> --issue c_domain.com_rsa e funciona, mas assim que eu adiciono outro argumento como ./<script name> --issue c_domain.com_rsa c_www.domain.com_rsa ele não funciona. O que estou fazendo errado? Script está abaixo:

#!/bin/bash

if [ "$1" = "--issue" ]; then
  CERTNAME="${2}"

else
  CERTNAME=$(echo "${2}" | sed -n "s/.*'\([^']\+\)'.*//p")

fi
  CERTFILE=$(echo "${CERTNAME}" | cut -d'_' -f 2)
  CERTTYPE=$(echo "${CERTNAME}" | cut -d'_' -f 3)

if [ -z "$CERTNAME" ] || [ -z "$CERTFILE" ] || [ -z "$CERTTYPE" ]; then
  echo "error, can't figure out CERTNAME or CERTFILE or CERTTYPE"
  exit 1
fi

ZCLI=$(locate zcli 2>/dev/null | egrep "test/bin/zcli$")
[ -z "$ZCLI" ] && ZCLI=$(which zcli)
[ -z "$ZCLI" ] && ZCLI=$(find / -name zcli | egrep "test/bin/zcli$")

if [ -z "$ZCLI" ]; then
  echo "Can't find zcli command"
  exit 1
fi


ACMEHOME="/root/certs/"
ACMEOPTIONS="--standalone --httpport 88"
TEST="--test --days 0"

case "$CERTTYPE" in
  ecc)
    ACMEKEY="--keylength ec-256"
    CERTDIR=$ACMEHOME/${CERTFILE}_${CERTTYPE}
    ;;
  rsa)
    ACMEKEY="--keylength 2048"
    CERTDIR=$ACMEHOME/${CERTFILE}
    ;;
  *)
   echo "error: wrong CERTTYPE"
   exit 1
esac

 if [ -d $CERTDIR ]; then
   # certificate renewal
   ACMEACTION="--renew"
   if [ "$CERTTYPE" = "ecc" ]; then
     ACMEKEY="--ecc"
   fi
else
  # certificate issuance
  ACMEACTION="--issue"
fi

$ACMEHOME/acme.sh $TEST $ACMEOPTIONS $ACMEACTION -d ${CERTFILE} $ACMEKEY

# key
key=$(cat $CERTDIR/${CERTFILE}.key)
key=${key//$'\n'/\n}

# crt
crt=$(cat $CERTDIR/fullchain.cer)
crt=${crt//$'\n'/\n}

echo "Catalog.SSL.Certificates.setRawCertificate ${CERTNAME} \"$crt\" " > 
$CERTDIR/zcli_${CERTFILE}.script 
$ZCLI $CERTDIR/zcli_${CERTFILE}.script
if [ $? -ne 0 ]; then
echo "Catalog.SSL.Certificates.importCertificate ${CERTNAME} { private_key: 
\"$key\", public_cert: \"$crt\" }" > $CERTDIR/zcli_${CERTFILE}.script
$ZCLI $CERTDIR/zcli_${CERTFILE}.script
fi

echo "Done!"
    
por TeNaJ Systems 16.11.2017 / 23:20

1 resposta

0

Não sei o que está acontecendo no restante do seu script, mas você não está lidando corretamente com os parâmetros posicionais. A configuração de CERTNAME to $@ irá ajustá-lo para uma string contendo todos os parâmetros, incluindo --include . Então você está executando cut nesta string, que não tenho certeza do que você espera fazer. Se você quiser dar um loop nos parâmetros, você pode fazer algo assim:

#!/bin/bash

if [[ "$1" = "--issue" ]]; then
   certs=("${@:2}")
else
   :
   # something else here
fi

for cert in "${certs[@]}"; do
   echo "$cert"
   # process each cert here
done

exit

Dado seu último exemplo, isso será impresso:

c_domain.com_rsa
c_www.domain.com_rsa

Isso coloca todos os seus parâmetros posicionais excluindo $1 em uma matriz e faz um loop sobre ela. Se você quiser colocar o restante dos parâmetros em uma string, apenas remova os parênteses assim: certs="${@:2}"

Usar $@ dessa maneira é um pouco confuso: quando você diz "$@" , ele expande os parâmetros posicionais em palavras, ou seja, $1 .. $n . No entanto, usá-lo em um contexto de matriz, como o que estou fazendo, incluirá $0 , que é o nome do script. É por isso que estou começando a fatia no elemento 2.

Como eu disse, há muitas outras coisas acontecendo aqui, mas isso deve responder à pergunta sobre parâmetros.

    
por 17.11.2017 / 23:38