mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-04-30 07:22:44 +00:00
Merge 01f45f6275e552f86cdddb9c199f7fafdc8b86fb into 90dda23f3345a6191faa2c99c1ddf5ccd10758b5
This commit is contained in:
commit
614c0e549c
105
le.sh
105
le.sh
@ -51,7 +51,7 @@ _debug() {
|
|||||||
_exists() {
|
_exists() {
|
||||||
cmd="$1"
|
cmd="$1"
|
||||||
if [ -z "$cmd" ] ; then
|
if [ -z "$cmd" ] ; then
|
||||||
_err "Usage: _exists cmd"
|
_err "Usage: ${FUNCNAME[0]} CMD"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
command -v $cmd >/dev/null 2>&1
|
command -v $cmd >/dev/null 2>&1
|
||||||
@ -75,12 +75,12 @@ _h2b() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
#options file
|
# args: OPTIONS FILE
|
||||||
_sed_i() {
|
_sed_i() {
|
||||||
options="$1"
|
options="$1"
|
||||||
filename="$2"
|
filename="$2"
|
||||||
if [ -z "$filename" ] ; then
|
if [ -z "$filename" ] ; then
|
||||||
_err "Usage:_sed_i options filename"
|
_err "Usage: ${FUNCNAME[0]} OPTIONS FILENAME"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -94,13 +94,13 @@ _sed_i() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: file startline endline
|
# args: FILE STARTLINE ENDLINE
|
||||||
_getfile() {
|
_getfile() {
|
||||||
filename="$1"
|
filename="$1"
|
||||||
startline="$2"
|
startline="$2"
|
||||||
endline="$3"
|
endline="$3"
|
||||||
if [ -z "$endline" ] ; then
|
if [ -z "$endline" ] ; then
|
||||||
_err "Usage: file startline endline"
|
_err "Usage: ${FUNCNAME[0]} FILE STARTLINE ENDLINE"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -121,10 +121,9 @@ _getfile() {
|
|||||||
_debug j $j
|
_debug j $j
|
||||||
|
|
||||||
sed -n $i,${j}p "$filename"
|
sed -n $i,${j}p "$filename"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: multiline
|
# args: [multiline]
|
||||||
_base64() {
|
_base64() {
|
||||||
if [ "$1" ] ; then
|
if [ "$1" ] ; then
|
||||||
openssl base64 -e
|
openssl base64 -e
|
||||||
@ -133,7 +132,7 @@ _base64() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: multiline
|
# args: [multiline]
|
||||||
_dbase64() {
|
_dbase64() {
|
||||||
if [ "$1" ] ; then
|
if [ "$1" ] ; then
|
||||||
openssl base64 -d -A
|
openssl base64 -d -A
|
||||||
@ -142,12 +141,12 @@ _dbase64() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: hashalg
|
# args: HASH-ALG
|
||||||
#Output Base64-encoded digest
|
# output: base64-encoded digest
|
||||||
_digest() {
|
_digest() {
|
||||||
alg="$1"
|
alg="$1"
|
||||||
if [ -z "$alg" ] ; then
|
if [ -z "$alg" ] ; then
|
||||||
_err "Usage: _digest hashalg"
|
_err "Usage: ${FUNCNAME[0]} HASH-ALG"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -157,16 +156,15 @@ _digest() {
|
|||||||
_err "$alg is not supported yet"
|
_err "$alg is not supported yet"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: keyfile hashalg
|
# args: KEYFILE HASH-ALG
|
||||||
#Output: Base64-encoded signature value
|
# output: base64-encoded signature value
|
||||||
_sign() {
|
_sign() {
|
||||||
keyfile="$1"
|
keyfile="$1"
|
||||||
alg="$2"
|
alg="$2"
|
||||||
if [ -z "$alg" ] ; then
|
if [ -z "$alg" ] ; then
|
||||||
_err "Usage: _sign keyfile hashalg"
|
_err "Usage: ${FUNCNAME[0]} KEYFILE HASH-ALG"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -176,7 +174,6 @@ _sign() {
|
|||||||
_err "$alg is not supported yet"
|
_err "$alg is not supported yet"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ss() {
|
_ss() {
|
||||||
@ -206,11 +203,11 @@ _ss() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
#domain [2048]
|
# args: ACCOUNT-DOMAIN [LENGTH] (default:2048)
|
||||||
createAccountKey() {
|
createAccountKey() {
|
||||||
_info "Creating account key"
|
_info "Creating account key"
|
||||||
if [ -z "$1" ] ; then
|
if [ -z "$1" ] ; then
|
||||||
echo Usage: createAccountKey account-domain [2048]
|
_err "Usage: $0 ${FUNCNAME[0]} ACCOUNT-DOMAIN [LENGTH] (default:2048)"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -234,14 +231,13 @@ createAccountKey() {
|
|||||||
#generate account key
|
#generate account key
|
||||||
openssl genrsa $length 2>/dev/null > "$ACCOUNT_KEY_PATH"
|
openssl genrsa $length 2>/dev/null > "$ACCOUNT_KEY_PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#domain length
|
# args: DOMAIN [LENGTH] (default:2048/256 for ec-)
|
||||||
createDomainKey() {
|
createDomainKey() {
|
||||||
_info "Creating domain key"
|
_info "Creating domain key"
|
||||||
if [ -z "$1" ] ; then
|
if [ -z "$1" ] ; then
|
||||||
echo Usage: createDomainKey domain [2048]
|
_err "Usage: $0 ${FUNCNAME[0]} DOMAIN [LENGTH] (default:2048/256 for ec-)"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -295,14 +291,13 @@ createDomainKey() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# domain domainlist
|
# args: DOMAIN [DOMAINLIST]
|
||||||
createCSR() {
|
createCSR() {
|
||||||
_info "Creating csr"
|
_info "Creating csr"
|
||||||
if [ -z "$1" ] ; then
|
if [ -z "$1" ] ; then
|
||||||
echo Usage: $0 domain [domainlist]
|
_err "Usage: $0 ${FUNCNAME[0]} DOMAIN [DOMAINLIST]"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
domain=$1
|
domain=$1
|
||||||
@ -327,7 +322,6 @@ createCSR() {
|
|||||||
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\n[SAN]\nsubjectAltName=$alt" > "$DOMAIN_SSL_CONF"
|
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\n[SAN]\nsubjectAltName=$alt" > "$DOMAIN_SSL_CONF"
|
||||||
openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" -reqexts SAN -config "$DOMAIN_SSL_CONF" -out "$CSR_PATH"
|
openssl req -new -sha256 -key "$CERT_KEY_PATH" -subj "/CN=$domain" -reqexts SAN -config "$DOMAIN_SSL_CONF" -out "$CSR_PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_urlencode() {
|
_urlencode() {
|
||||||
@ -345,7 +339,6 @@ _time2str() {
|
|||||||
if date -u -r $1 2>/dev/null ; then
|
if date -u -r $1 2>/dev/null ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_stat() {
|
_stat() {
|
||||||
@ -360,11 +353,11 @@ _stat() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#keyfile
|
# args: KEYFILE
|
||||||
_calcjwk() {
|
_calcjwk() {
|
||||||
keyfile="$1"
|
keyfile="$1"
|
||||||
if [ -z "$keyfile" ] ; then
|
if [ -z "$keyfile" ] ; then
|
||||||
_err "Usage: _calcjwk keyfile"
|
_err "Usage: ${FUNCNAME[0]} KEYFILE"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
EC_SIGN=""
|
EC_SIGN=""
|
||||||
@ -434,7 +427,8 @@ _calcjwk() {
|
|||||||
|
|
||||||
_debug HEADER "$HEADER"
|
_debug HEADER "$HEADER"
|
||||||
}
|
}
|
||||||
# body url [needbase64]
|
|
||||||
|
# args: BODY URL [needbase64]
|
||||||
_post() {
|
_post() {
|
||||||
body="$1"
|
body="$1"
|
||||||
url="$2"
|
url="$2"
|
||||||
@ -456,10 +450,9 @@ _post() {
|
|||||||
_sed_i "s/^ *//g" "$HTTP_HEADER"
|
_sed_i "s/^ *//g" "$HTTP_HEADER"
|
||||||
fi
|
fi
|
||||||
echo -n "$response"
|
echo -n "$response"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# url getheader
|
# args: URL [getheader]
|
||||||
_get() {
|
_get() {
|
||||||
url="$1"
|
url="$1"
|
||||||
onlyheader="$2"
|
onlyheader="$2"
|
||||||
@ -482,7 +475,7 @@ _get() {
|
|||||||
return $ret
|
return $ret
|
||||||
}
|
}
|
||||||
|
|
||||||
# url payload needbase64 keyfile
|
# args: URL PAYLOAD [needbase64 [KEYFILE]]
|
||||||
_send_signed_request() {
|
_send_signed_request() {
|
||||||
url=$1
|
url=$1
|
||||||
payload=$2
|
payload=$2
|
||||||
@ -527,11 +520,9 @@ _send_signed_request() {
|
|||||||
_debug response "$response"
|
_debug response "$response"
|
||||||
code="$(grep "^HTTP" $HTTP_HEADER | tail -1 | cut -d " " -f 2 | tr -d "\r\n" )"
|
code="$(grep "^HTTP" $HTTP_HEADER | tail -1 | cut -d " " -f 2 | tr -d "\r\n" )"
|
||||||
_debug code $code
|
_debug code $code
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: "FILE" "OPT" "=" "VALUE" [";"]
|
||||||
#setopt "file" "opt" "=" "value" [";"]
|
|
||||||
_setopt() {
|
_setopt() {
|
||||||
__conf="$1"
|
__conf="$1"
|
||||||
__opt="$2"
|
__opt="$2"
|
||||||
@ -539,7 +530,7 @@ _setopt() {
|
|||||||
__val="$4"
|
__val="$4"
|
||||||
__end="$5"
|
__end="$5"
|
||||||
if [ -z "$__opt" ] ; then
|
if [ -z "$__opt" ] ; then
|
||||||
echo usage: _setopt '"file" "opt" "=" "value" [";"]'
|
_err "Usage: ${FUNCNAME[0]} "'"FILE" "OPT" "=" "VALUE" [";"]'
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
if [ ! -f "$__conf" ] ; then
|
if [ ! -f "$__conf" ] ; then
|
||||||
@ -568,8 +559,8 @@ _setopt() {
|
|||||||
_debug "$(grep -H -n "^$__opt$__sep" $__conf)"
|
_debug "$(grep -H -n "^$__opt$__sep" $__conf)"
|
||||||
}
|
}
|
||||||
|
|
||||||
#_savedomainconf key value
|
# args: KEY VALUE
|
||||||
#save to domain.conf
|
# job: save to domain.conf
|
||||||
_savedomainconf() {
|
_savedomainconf() {
|
||||||
key="$1"
|
key="$1"
|
||||||
value="$2"
|
value="$2"
|
||||||
@ -580,7 +571,7 @@ _savedomainconf() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#_saveaccountconf key value
|
# args: KEY VALUE
|
||||||
_saveaccountconf() {
|
_saveaccountconf() {
|
||||||
key="$1"
|
key="$1"
|
||||||
value="$2"
|
value="$2"
|
||||||
@ -591,6 +582,7 @@ _saveaccountconf() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: CONTENT
|
||||||
_startserver() {
|
_startserver() {
|
||||||
content="$1"
|
content="$1"
|
||||||
|
|
||||||
@ -628,9 +620,9 @@ _startserver() {
|
|||||||
|
|
||||||
_stopserver() {
|
_stopserver() {
|
||||||
pid="$1"
|
pid="$1"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: [DOMAIN]
|
||||||
_initpath() {
|
_initpath() {
|
||||||
|
|
||||||
if [ -z "$LE_WORKING_DIR" ]; then
|
if [ -z "$LE_WORKING_DIR" ]; then
|
||||||
@ -718,10 +710,8 @@ _initpath() {
|
|||||||
if [ -z "$CERT_FULLCHAIN_PATH" ] ; then
|
if [ -z "$CERT_FULLCHAIN_PATH" ] ; then
|
||||||
CERT_FULLCHAIN_PATH="$domainhome/fullchain.cer"
|
CERT_FULLCHAIN_PATH="$domainhome/fullchain.cer"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_apachePath() {
|
_apachePath() {
|
||||||
httpdroot="$(apachectl -V | grep HTTPD_ROOT= | cut -d = -f 2 | tr -d '"' )"
|
httpdroot="$(apachectl -V | grep HTTPD_ROOT= | cut -d = -f 2 | tr -d '"' )"
|
||||||
httpdconfname="$(apachectl -V | grep SERVER_CONFIG_FILE= | cut -d = -f 2 | tr -d '"' )"
|
httpdconfname="$(apachectl -V | grep SERVER_CONFIG_FILE= | cut -d = -f 2 | tr -d '"' )"
|
||||||
@ -804,7 +794,7 @@ _clearup () {
|
|||||||
_restoreApache
|
_restoreApache
|
||||||
}
|
}
|
||||||
|
|
||||||
# webroot removelevel tokenfile
|
# args: WEBROOT REMOVE-LEVEL [TOKENFILE]
|
||||||
_clearupwebbroot() {
|
_clearupwebbroot() {
|
||||||
__webroot="$1"
|
__webroot="$1"
|
||||||
if [ -z "$__webroot" ] ; then
|
if [ -z "$__webroot" ] ; then
|
||||||
@ -826,12 +816,12 @@ _clearupwebbroot() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: webroot|apache|dns|no DOMAIN [SUBDOMAIN,...|no] [KEY-LENGTH|no] [CERT-PATH [REAL-KEY-PATH [CA-CERT-PATH [RELOAD-CMD]]]]"
|
||||||
issue() {
|
issue() {
|
||||||
if [ -z "$2" ] ; then
|
if [ -z "$2" ] ; then
|
||||||
_err "Usage: le issue webroot|no|apache|dns a.com [www.a.com,b.com,c.com]|no [key-length]|no"
|
_err "Usage: $0 ${FUNCNAME[0]} webroot|apache|dns|no DOMAIN [SUBDOMAIN,...|no] [KEY-LENGTH|no] [CERT-PATH [REAL-KEY-PATH [CA-CERT-PATH [RELOAD-CMD]]]]"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
Le_Webroot="$1"
|
Le_Webroot="$1"
|
||||||
@ -1066,7 +1056,6 @@ issue() {
|
|||||||
_err "Please add the TXT records to the domains, and retry again."
|
_err "Please add the TXT records to the domains, and retry again."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$dnsadded" == '1' ] ; then
|
if [ "$dnsadded" == '1' ] ; then
|
||||||
@ -1117,7 +1106,6 @@ issue() {
|
|||||||
webroot_owner=$(_stat $Le_Webroot)
|
webroot_owner=$(_stat $Le_Webroot)
|
||||||
_debug "Changing owner/group of .well-known to $webroot_owner"
|
_debug "Changing owner/group of .well-known to $webroot_owner"
|
||||||
chown -R $webroot_owner "$Le_Webroot/.well-known"
|
chown -R $webroot_owner "$Le_Webroot/.well-known"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1233,13 +1221,13 @@ issue() {
|
|||||||
|
|
||||||
|
|
||||||
installcert $Le_Domain "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd"
|
installcert $Le_Domain "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: DOMAIN
|
||||||
renew() {
|
renew() {
|
||||||
Le_Domain="$1"
|
Le_Domain="$1"
|
||||||
if [ -z "$Le_Domain" ] ; then
|
if [ -z "$Le_Domain" ] ; then
|
||||||
_err "Usage: $0 domain.com"
|
_err "Usage: $0 ${FUNCNAME[0]} DOMAIN"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1306,13 +1294,13 @@ renewAll() {
|
|||||||
|
|
||||||
renew "$d"
|
renew "$d"
|
||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args: DOMAIN [CERT-FILE-PATH|no] [KEY-FILE-PATH|no] [CA-CERT-FILE-PATH|no] [RELOAD-CMD|no]
|
||||||
installcert() {
|
installcert() {
|
||||||
Le_Domain="$1"
|
Le_Domain="$1"
|
||||||
if [ -z "$Le_Domain" ] ; then
|
if [ -z "$Le_Domain" ] ; then
|
||||||
_err "Usage: $0 domain.com [cert-file-path]|no [key-file-path]|no [ca-cert-file-path]|no [reloadCmd]|no"
|
_err "Usage: $0 ${FUNCNAME[0]} DOMAIN [CERT-FILE-PATH|no] [KEY-FILE-PATH|no] [CA-CERT-FILE-PATH|no] [RELOAD-CMD|no]"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1394,8 +1382,7 @@ uninstallcronjob() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# job: detect profile file if not specified as environment variable
|
||||||
# Detect profile file if not specified as environment variable
|
|
||||||
_detect_profile() {
|
_detect_profile() {
|
||||||
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
|
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
|
||||||
echo "$PROFILE"
|
echo "$PROFILE"
|
||||||
@ -1476,12 +1463,12 @@ USER_AGENT=\"le.sh client: $PROJECT\"
|
|||||||
|
|
||||||
_precheck() {
|
_precheck() {
|
||||||
if ! _exists "curl" && ! _exists "wget"; then
|
if ! _exists "curl" && ! _exists "wget"; then
|
||||||
_err "Please install curl or wget first, we need to access http resources."
|
_err "Please install curl or wget first, we need it to access http resources."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _exists "crontab" ; then
|
if ! _exists "crontab" ; then
|
||||||
_err "Please install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'."
|
_err "Please install crontab first, try to install 'cron', 'crontab', 'crontabs' or 'vixie-cron'."
|
||||||
_err "We need to set cron job to renew the certs automatically."
|
_err "We need to set cron job to renew the certs automatically."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -1515,11 +1502,11 @@ install() {
|
|||||||
_info "Installing to $LE_WORKING_DIR"
|
_info "Installing to $LE_WORKING_DIR"
|
||||||
|
|
||||||
if ! mkdir -p "$LE_WORKING_DIR" ; then
|
if ! mkdir -p "$LE_WORKING_DIR" ; then
|
||||||
_err "Can not craete working dir: $LE_WORKING_DIR"
|
_err "Can not create working dir: $LE_WORKING_DIR"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp le.sh "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/le.sh"
|
cp $0 "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/le.sh"
|
||||||
|
|
||||||
if [ "$?" != "0" ] ; then
|
if [ "$?" != "0" ] ; then
|
||||||
_err "Install failed, can not copy le.sh"
|
_err "Install failed, can not copy le.sh"
|
||||||
@ -1538,7 +1525,7 @@ alias le.sh=\"$LE_WORKING_DIR/le.sh\"
|
|||||||
" > "$LE_WORKING_DIR/le.env"
|
" > "$LE_WORKING_DIR/le.env"
|
||||||
echo "" >> "$_profile"
|
echo "" >> "$_profile"
|
||||||
_setopt "$_profile" "source \"$LE_WORKING_DIR/le.env\""
|
_setopt "$_profile" "source \"$LE_WORKING_DIR/le.env\""
|
||||||
_info "OK, Close and reopen your terminal to start using le"
|
_info "OK, close and reopen your terminal to start using le"
|
||||||
else
|
else
|
||||||
_info "No profile is found, you will need to go into $LE_WORKING_DIR to use le.sh"
|
_info "No profile is found, you will need to go into $LE_WORKING_DIR to use le.sh"
|
||||||
fi
|
fi
|
||||||
@ -1586,7 +1573,7 @@ version() {
|
|||||||
showhelp() {
|
showhelp() {
|
||||||
version
|
version
|
||||||
echo "Usage: le.sh [command] ...[args]....
|
echo "Usage: le.sh [command] ...[args]....
|
||||||
Avalible commands:
|
Available commands:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
Install le.sh to your system.
|
Install le.sh to your system.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user