我正在尝试设置下面的脚本以在命令行上输入多个参数。我正在使用脚本从 LetsEncrypt 请求 ssl 证书。该脚本当前一次获取一个域,但我希望能够将其设置为接受多个命令行参数,以便我能够使用它来请求具有多个备用名称的域的证书(例如:domain.txt)。 com 和 www.domain.com)我尝试更改CERTNAME="${2}"
为CERTNAME="$@"
和CERTNAME=$(echo "${2}" | sed -n "s/.*'\([^']\+\)'.*/\1/p")
,CERTNAME=$(echo "$@" | sed -n "s/.*'\([^']\+\)'.*/\1/p")
但它一直卡在echo "error: wrong CERTTYPE"
.我像这样运行脚本./<script name> --issue c_domain.com_rsa
并且它可以工作,但是一旦我添加另一个像这样的参数,./<script name> --issue c_domain.com_rsa c_www.domain.com_rsa
它就不起作用了。我做错了什么?脚本如下:
#!/bin/bash
if [ "$1" = "--issue" ]; then
CERTNAME="${2}"
else
CERTNAME=$(echo "${2}" | sed -n "s/.*'\([^']\+\)'.*/\1/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!"
答案1
我不确定脚本的其余部分发生了什么,但您没有正确处理位置参数。设置CERTNAME
为$@
会将其设置为包含所有参数的字符串,包括--include
.然后你就在这个字符串上运行cut
,我不确定你期望做什么。如果你想循环参数,你可以这样做:
#!/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
鉴于您的最后一个示例,这将打印:
c_domain.com_rsa
c_www.domain.com_rsa
这会将所有位置参数(排除)放入$1
一个数组中并对其进行循环。如果要将其余参数放入字符串中,只需删除括号,如下所示:certs="${@:2}"
使用$@
这种方式有点令人困惑:当你说"$@"
它将位置参数扩展为单词时,即$1
......。$n
但是,像我一样在数组上下文中使用它将会 include $0
,这是脚本的名称。这就是为什么我从元素 2 开始切片。
就像我说的,这里还发生了很多其他事情,但这应该回答有关参数的问题。