Shell脚本学习参考
#!/usr/bin/env bash
# WIKI: https://httpsok.com/doc/
# This script only supports bash, do not support posix sh.
# If you have the problem like Syntax error: "(" unexpected (expecting "fi"),
# Try to run "bash -version" to check the version.
# Try to visit WIKI to find a solution.
################################################
NGINX_BIN=nginx
# NGINX_CONFIG=/etc/nginx/nginx.conf
# NGINX_CONFIG_HOME=/etc/nginx
##################################################
VER=1.18.0
PROJECT_NAME="httpsok"
PROJECT_ENTRY="httpsok.sh"
PROJECT_HOME="$HOME/.httpsok"
PROJECT_BACKUPS="$HOME/.httpsok/backups"
PROJECT_ENTRY_BIN="$PROJECT_HOME/$PROJECT_ENTRY"
PROJECT_TOKEN_FILE="$PROJECT_HOME/token"
HTTPSOK_UUID_FILE="$PROJECT_HOME/uuid"
PROJECT_LOG_FILE="$PROJECT_HOME/$PROJECT_NAME.log"
HTTPSOK_TOKEN=""
HTTPSOK_UUID=""
HTTPSOK_HOME_URL="https://httpsok.com/"
BASE_API_URL="https://api.httpsok.com/v1/nginx"
SCRIPT_URL="https://get.httpsok.com/"
latest_code=""
preparse=""
OS=""
NGINX_VERSION=""
MODE="normal"
_upper_case() {
tr '[a-z]' '[A-Z]'
}
_lower_case() {
tr '[A-Z]' '[a-z]'
}
_startswith() {
_str="$1"
_sub="$2"
echo "$_str" | grep -- "^$_sub" >/dev/null 2>&1
}
_endswith() {
_str="$1"
_sub="$2"
echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1
}
_contains() {
_str="$1"
_sub="$2"
echo "$_str" | grep -- "$_sub" >/dev/null 2>&1
}
_time() {
date -u "+%s"
}
_math() {
_m_opts="$@"
printf "%s" "$(($_m_opts))"
}
_err() {
echo -e "\033[31m$(date +"%F %T") $@\033[0m" 1>&2
}
_info() {
echo -e "$(date +"%F %T") $@" 1>&2
}
_suc() {
echo -e "\033[32m$(date +"%F %T") $@\033[0m" 1>&2
}
_random_md5() {
head -c 32 /dev/urandom | md5sum | awk '{print $1}'
}
TRACE_ID=$(_random_md5)
_exists() {
cmd="$1"
if [ -z "$cmd" ]; then
_usage "Usage: _exists cmd"
return 1
fi
if eval type type >/dev/null 2>&1; then
eval type "$cmd" >/dev/null 2>&1
elif command >/dev/null 2>&1; then
command -v "$cmd" >/dev/null 2>&1
else
which "$cmd" >/dev/null 2>&1
fi
ret="$?"
return $ret
}
showWelcome() {
echo
echo -e "\033[1;36mHttpsok make SSL easy. $HTTPSOK_HOME_URL \033[0m"
echo -e "\033[1;36mversion: $VER\033[0m"
echo -e "\033[1;36mTraceID: $TRACE_ID\033[0m"
echo
}
_mkdirs() {
_dir="$1"
if [ ! "$_dir" = "" ]; then
if [ ! -d "$_dir" ]; then
mkdir -p "$_dir" && _suc "Create directory $_dir success."
fi
fi
}
_initpath() {
_mkdirs "$PROJECT_HOME"
_mkdirs "$PROJECT_BACKUPS"
}
_no_nginx_here(){
echo
_err "Can’t detected nginx\n"
_err "Please confirm that nginx has been successfully installed on your system"
_detected_is_root_run
echo
echo
exit
}
_detected_is_root_run(){
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
if [ "$(id -u)" -ne 0 ]; then
echo -e "${YELLOW}Detected non-root user running, it's recommended to run as root user.${NC}\n"
fi
}
_init_params() {
if [ "$OS" != "" ]; then
return 0
fi
if [ -f /etc/os-release ]; then
OS=$(grep 'PRETTY_NAME' /etc/os-release | awk -F '=' '{print $2}' | tr -d '"')
elif [ -f /etc/redhat-release ]; then
OS=$(cat /etc/redhat-release)
elif [ -f /etc/alpine-release ]; then
OS="alpine"
else
_err "Unsupported operating system"
exit 1
fi
# NGINX_BIN=nginx
$NGINX_BIN -V > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "no nginx in PATH, find the nginx"
pid=$(ps -e | grep nginx | grep -v 'grep' | head -n 1 | awk '{print $1}')
if [ -n "$pid" ]; then
NGINX_BIN=$(readlink -f /proc/"$pid"/exe)
# echo "NGINX_BIN=$NGINX_BIN"
# again to verify
$NGINX_BIN -V > /dev/null 2>&1
if [ $? -ne 0 ]; then
_no_nginx_here
else
echo "Nginx executable path: $NGINX_BIN"
fi
else
_no_nginx_here
fi
fi
NGINX_VERSION=$($NGINX_BIN -v 2>&1 | awk -F ': ' '{print $2}' | head -n 1 | head -c 20)
# user can setting
if [ -z "$NGINX_CONFIG" ]; then
# Use a running nginx first
NGINX_CONFIG=$(ps -eo pid,cmd | grep nginx | grep master | grep '\-c' | awk -F '-c' '{print $2}' | sed 's/ //g')
fi
# fix the NGINX_CONFIG equals nginx.conf bug
if [ -z "$NGINX_CONFIG" ] || [ "$NGINX_CONFIG" = "nginx.conf" ]; then
NGINX_CONFIG=$($NGINX_BIN -t 2>&1 | grep 'configuration' | head -n 1 | awk -F 'file' '{print $2}' | awk '{print $1}' )
fi
if [ -z "$NGINX_CONFIG_HOME" ]; then
NGINX_CONFIG_HOME=$(dirname "$NGINX_CONFIG")
fi
_init_httpsok_params
_info "os-name: $OS"
_info "version: $NGINX_VERSION"
_info "nginx-config: $NGINX_CONFIG"
_info "nginx-config-home: $NGINX_CONFIG_HOME"
_info "nginx-bin: $NGINX_BIN"
_info "httpsok-uuid: $HTTPSOK_UUID"
if [ "$NGINX_CONFIG_HOME" = "." ]; then
echo ""
echo ""
echo -e "\033[31m获取nginx配置文件失败, 请您根据实际情况,手动设置\033[0m"
echo ""
echo -e "\033[1;36m修改文件 $PROJECT_ENTRY_BIN\033[0m"
echo ""
echo "################################################"
echo "# 配置示例 "
echo "NGINX_CONFIG=/etc/nginx/nginx.conf"
echo "NGINX_CONFIG_HOME=/etc/nginx"
echo "##################################################"
echo ""
exit 0
fi
showWelcome
}
_init_httpsok_params() {
if [ "$HTTPSOK_UUID" != "" ]; then
return 0
fi
if [ -f "$HTTPSOK_UUID_FILE" ]; then
HTTPSOK_UUID=$(cat "$HTTPSOK_UUID_FILE")
fi
if [ "$HTTPSOK_UUID" != "" ]; then
# _info "load HTTPSOK_UUID from $HTTPSOK_UUID_FILE: $HTTPSOK_UUID"
return 0
fi
_initpath
if [ -f "/sys/class/dmi/id/product_uuid" ]; then
HTTPSOK_UUID=$(cat /sys/class/dmi/id/product_uuid)
if [ "$HTTPSOK_UUID" != "" ]; then
echo "$HTTPSOK_UUID" > "$HTTPSOK_UUID_FILE"
# _info "save HTTPSOK_UUID from product_uuid to $HTTPSOK_UUID_FILE: $HTTPSOK_UUID"
return 0
fi
fi
HTTPSOK_UUID=$(_random_md5)
echo "$HTTPSOK_UUID" > "$HTTPSOK_UUID_FILE"
# _info "save HTTPSOK_UUID to $HTTPSOK_UUID_FILE: $HTTPSOK_UUID"
}
_inithttp() {
_init_httpsok_params
_H0="Content-Type: text/plain"
_H1="httpsok-token: $HTTPSOK_TOKEN"
_H2="httpsok-version: $VER"
_H3="os-name: $OS"
_H4="nginx-version: $NGINX_VERSION"
_H5="nginx-config-home: $NGINX_CONFIG_HOME"
_H6="nginx-config: $NGINX_CONFIG"
_H7="trace-id: $TRACE_ID"
_H8="mode: $MODE"
_H9="httpsok-uuid: $HTTPSOK_UUID"
}
_post() {
_inithttp
url="${BASE_API_URL}$1"
body="$2"
curl -s -X POST -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "$body" "$url"
}
_post2() {
_inithttp
url="${BASE_API_URL}$1"
fiename="$2"
curl -s -X POST -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "@$fiename" "$url"
}
_get() {
_inithttp
url="${BASE_API_URL}$1"
curl -s -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" "$url"
}
_upload() {
_inithttp
url="${BASE_API_URL}/upload?code=$1"
_F1="cert=@\"$2\""
_F2="certKey=@\"$3\""
curl -s -X POST -H "Content-Type: multipart/form-data" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" -F $_F1 -F $_F2 "$url" 2>&1
}
_put() {
_inithttp
url="${BASE_API_URL}$1"
body="$2"
curl -s -X PUT -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "$body" "$url"
}
_remote_log() {
type="$1"
code="$2"
msg="$3"
_put "/log/$type?code=$code" "$msg"
}
_done() {
_t=$(_time)
_get "/done?t=$_t"
}
_remote_uninstall(){
_load_token
_t=$(_time)
_get "/uninstall?t=$_t"
}
_create_file() {
local _code="$1"
local file_path="$2"
if [ ! -e "$file_path" ]; then
dir_path=$(dirname "$file_path")
mkdir -p "$dir_path"
touch "$file_path"
_suc "$_code" "File created: $file_path"
else
# backup the files
if [ -f "$file_path" ]; then
_filename=${file_path##*/}
_date=$(date +"%Y%m%d%H%M%S")
backup_file_path="$PROJECT_BACKUPS/$_filename.$_date"
if [ -f "$backup_file_path" ]; then
_err "$_code" "Backup file already exists: $backup_file_path"
else
mv "$file_path" "$backup_file_path"
_suc "$_code" "Backup the file $file_path to $backup_file_path"
fi
fi
fi
}
_check() {
depth=$1
code=$2
cert_file=$3
cert_key_file=$4
url="/check?code=$code"
if [ $depth -le 0 ]; then
_err "The maximum number of attempts exceeded"
else
resp=$(_get "$url")
status=$(echo "$resp" | head -n 1)
case $status in
"1")
# _info "$code $cert_file The new certificate has been updated"
md5_line=$(echo "$resp" | awk 'NR==2')
cert_file_md5=$(echo $md5_line | awk -F ',' '{print $1}')
cert_key_file_md5=$(echo $md5_line | awk -F ',' '{print $2}')
tmp_cert_file="/tmp/$code.cer"
tmp_cert_key_file="/tmp/$code.key"
_get "/cert/$code.cer" > "$tmp_cert_file" && _get "/cert/$code.key" > "$tmp_cert_key_file"
# md5 check
tmp_cert_md5=$(md5sum "$tmp_cert_file" | awk '{print $1}')
tmp_cert_key_md5=$(md5sum "$tmp_cert_key_file" | awk '{print $1}')
if [ "$cert_file_md5" = "$tmp_cert_md5" ] && [ "$cert_key_file_md5" = "$tmp_cert_key_md5" ]; then
# if local_cert_file not here. need to create the file
_create_file "$code" "$cert_file" && _create_file "$code" "$cert_key_file"
mv "$tmp_cert_file" "$cert_file" && mv "$tmp_cert_key_file" "$cert_key_file"
_suc "$code $cert_file New cert updated(证书更新成功)"
_remote_log "cert-updated-success" "$code" "New cert updated(证书更新成功)"
echo "latest_code $code"
else
_err "$code $cert_file New cert update failed (md5 not match)"
_remote_log "cert-updated-failed" "$code" "New cert update failed (md5 not match): cert_file_md5=$cert_file_md5,tmp_cert_md5=$tmp_cert_md5,cert_key_file_md5=$cert_key_file_md5,tmp_cert_key_md5=$tmp_cert_key_md5"
fi
;;
"2")
_info "$code $cert_file Processing, please just wait(正在处理中,请稍等)..."
sleep 10
_check $((depth - 1)) "$code" "$cert_file" "$cert_key_file"
;;
"3")
_info "$code $cert_file Cert valid(证书有效)"
;;
"12")
_err "$code $cert_file DNS CNAME invalid(DNS检测不通过)"
;;
"13")
_err "$code $cert_file code invalid(非法请求)"
;;
*)
_err "$code $cert_file $resp"
;;
esac
fi
}
_save_token() {
_token="$1"
_check_token "$_token"
_initpath
if [ ! "$_token" = "" ]; then
echo "$_token" > "$PROJECT_TOKEN_FILE"
_suc "save token $_token to $PROJECT_TOKEN_FILE"
fi
}
_load_token() {
if [ "$HTTPSOK_TOKEN" = "" ]; then
HTTPSOK_TOKEN=$(cat "$PROJECT_TOKEN_FILE")
fi
}
_show_token() {
_load_token
echo -e "Your token is: \033[1;36m$HTTPSOK_TOKEN\033[0m"
}
_check_token() {
_token="$1"
if [ ! "$_token" = "" ]; then
HTTPSOK_TOKEN="$_token"
fi
if [ "$HTTPSOK_TOKEN" = "" ]; then
_err "httpsok's token can not empty"
exit 4
fi
_init_params
status=$(_get "/status")
# _info "status >> $status"
if [ "$status" != "ok" ]; then
# echo -e "\033[1;36mTraceID: $TRACE_ID\033[0m"
_err "Invalid token: \033[1;36m$HTTPSOK_TOKEN\033[0m"
_info "Please copy your token from '$HTTPSOK_HOME_URL'"
echo
_err "$status"
exit 4
fi
return 0
}
# Limit the maximum nesting level
_include_max_calls=20
_include_global_count=0
__process_include() {
# echo "-_include_global_count: $_include_global_count --------------------------------------------------"
# echo Recursive call, degree incremented by one
((_include_global_count++))
if [ $_include_global_count -gt $_include_max_calls ]; then
echo "#######################################################"
echo "##### warning: Maximum recursion limit reached."
echo "#######################################################"
cat /dev/stdin
return 0
fi
tmp=$(cat /dev/stdin | awk -v NGINX_CONFIG=">$NGINX_CONFIG:" -v NGINX_CONFIG_HOME="$NGINX_CONFIG_HOME" '{
original = $0
# Remove leading and trailing whitespace characters from each line
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
sub(/^[\t ]*|[\t ]*$/,"")
# Ignore the lines at the beginning of the file
if ($0 ~ /^>/) {
print original
next
}
# Determines if it starts with #, and if it does, ignores it
if ($0 ~ /^#/) {
# Replace the include in the comment
# gsub("include", "import")
print original
next
}
# Determine whether include is included
if ($0 ~ /^include /) {
# Ignore mime.types
if($0 ~ /mime\.types;/){
print "#import " original
next
}
# print "#import " $2
print "#import " original
# system("cat " $2)
# print ">> "
# ls /etc/nginx/conf.d/*.conf | xargs -I {} sed "s|^|{}:|" {}
# system("ls " $2 " | xargs -I {} sed \"s|^|{}:|\" {}")
# /etc/nginx/conf.d/*.conf;
# Replace ;
gsub(/;/, "")
# /etc/nginx/conf.d/*.conf
# Resolved to an include file
# print $2
# Deal with relative path issues
if (substr($2, 1, 1) != "/") {
$2 = NGINX_CONFIG_HOME "/" $2
}
# print "# " original
# The second way
# find . -maxdepth 1 -print0 | xargs -0 command
# system("find " $2 " -maxdepth 1 -print0 | xargs -0 -I {} sed \"s|^|>{}:|\" {}")
# just backup
# system("ls -1 " $2 " | xargs -I {} sed \"s|^|>{}:|\" {}")
# If the last line of the file is not newline, the file will not be parsed correctly
# system("ls -1 " $2 " 2>/dev/null | xargs -I {} cat {} ")
# Using sh has security implications deprecated
# system("ls -1 " $2 " 2>/dev/null | xargs -I {} sh -c \"cat {} && echo\" ")
#
# system("ls -1 " $2 " 2>/dev/null | xargs -I {} sed -n \"$p\" {} ")
# xargs -I {} awk -v FP="{}" "BEGIN{ print \"# include \" FP } {print} END{print ""} " {}
#system("ls -1 " $2 " 2>/dev/null | xargs -I {} awk \" {print} END {print \"\" } \" {} ")
#
# cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk \" {print} END {print \"\\\"\"\n\"\\\"\" } \" {} "
# cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk \"BEGIN {print \"\"{}\"\" } {print} END {print \n } \" {} "
# OK Add a newline character to the end of the file
# cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk \" {print} END {print \"\\n\" } \" {} "
# OK Add a newline character to the end of the file
# cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk '\'' {print} '\'' {} "
# OK add config file path
#cmd = "ls -1 " $2 " 2>/dev/null | xargs -I GG awk '\'' BEGIN {print \"#included GG;\" } {print} '\'' GG "
#cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk '\'' BEGIN {print \"#included {};\" } {print} '\'' {} "
cmd = "ls -1 " $2 " 2>/dev/null | xargs -I {} awk '\'' BEGIN {print \"#included-begin {};\" } {print} END{ print \"#included-end {};\" } '\'' {} "
# print cmd
system(cmd)
print ""
next
}
print original
}'
)
if echo "$tmp" | grep -v '#' | grep -q "include"; then
# Perform a recursive call
echo "$tmp" | __process_include
else
# End the recursive call
echo "$tmp"
fi
}
_preparse() {
_init_params
config_text=$(cat $NGINX_CONFIG | __process_include )
tmp_name="/tmp/2nLN3ZspTMGifYtO.tmp"
echo "$config_text" > $tmp_name
preparse=$(_post2 "/preparse" "$tmp_name")
rm -rf "$tmp_name" > /dev/null 2>&1
if [ "$preparse" = "" ]; then
return 4
fi
return 0
}
_upload_certs() {
while read row
do
if [ "$row" = "" ]; then
continue
fi
code=$(echo $row | awk -F ',' '{print $1}')
cert_file=$(echo $row | awk -F ',' '{print $2}')
cert_key_file=$(echo $row | awk -F ',' '{print $3}')
up_status=$(_upload "$code" "$cert_file" "$cert_key_file")
if [ "$up_status" != "ok" ]; then
continue
fi
done <<EOF
$preparse
EOF
}
_check_certs() {
while read row
do
if [ "$row" = "" ]; then
continue
fi
code=$(echo $row | awk -F ',' '{print $1}')
cert_file=$(echo $row | awk -F ',' '{print $2}')
cert_key_file=$(echo $row | awk -F ',' '{print $3}')
check_reposne=$(_check 60 "$code" "$cert_file" "$cert_key_file")
_code=$(echo "$check_reposne" | grep 'latest_code' | awk '{print $2}')
if [ -n "$_code" ]; then
latest_code="$_code"
fi
done <<EOF
$preparse
EOF
}
_check_dns() {
codes=$(echo "$preparse" | awk -F ',' '{print $1}' | tr '\n' ',' )
url="/checkDns"
resp=$(_get "$url")
status=$(echo "$resp" | head -n 1)
case $status in
"3")
_suc "DNS check pass(DNS检查通过)"
;;
"13")
_err "code invalid"
;;
*)
_err "$resp"
;;
esac
}
_reload_nginx() {
if [ "$latest_code" = "" ]; then
echo
_info "Nginx reload needless(无需重载)."
return 0
fi
(
# fixbug: signal process started
cd $NGINX_CONFIG_HOME
msg=$($NGINX_BIN -t 2>&1)
if [ $? != 0 ]; then
_remote_log "nginx-test-failed" "$latest_code" "$msg"
echo
_err "Nginx test failed(测试失败). \n\n$msg"
else
msg=$($NGINX_BIN -s reload 2>&1)
if [ $? -eq 0 ]; then
_remote_log "nginx-reload-success" "$latest_code" "Nginx reload success(重载成功)."
echo
_suc "Nginx reload success(重载成功)."
else
# Check if nginx is running
show_msg=$msg
pid=$(ps -e | grep nginx | grep -v 'grep' | head -n 1 | awk '{print $1}')
if [ -z "$pid" ]; then
msg="Nginx is not started(服务未启动). \n\n$msg"
show_msg="\033[33mNginx is not started. You can run \"service nginx start\" to start the Nginx(请重启服务). \033[31m\n\n$show_msg"
fi
_remote_log "nginx-reload-failed" "$latest_code" "$msg"
echo
_err "Nginx reload failed(重载失败). \n\n$show_msg"
fi
fi
)
}
version() {
echo "$PROJECT_ENTRY v$VER"
}
# Detect profile file if not specified as environment variable
_detect_profile() {
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
echo "$PROFILE"
return
fi
DETECTED_PROFILE=''
SHELLTYPE="$(basename "/$SHELL")"
if [ "$SHELLTYPE" = "bash" ]; then
if [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile"
fi
elif [ "$SHELLTYPE" = "zsh" ]; then
DETECTED_PROFILE="$HOME/.zshrc"
fi
if [ -z "$DETECTED_PROFILE" ]; then
if [ -f "$HOME/.profile" ]; then
DETECTED_PROFILE="$HOME/.profile"
elif [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile"
elif [ -f "$HOME/.zshrc" ]; then
DETECTED_PROFILE="$HOME/.zshrc"
fi
fi
if [ -z "$DETECTED_PROFILE" ]; then
if [ -f "/etc/profile" ]; then
DETECTED_PROFILE="/etc/profile"
fi
fi
echo "$DETECTED_PROFILE"
}
_tail_c() {
tail -c "$1" 2>/dev/null || tail -"$1"c
}
_setopt() {
__conf="$1"
__opt="$2"
__sep="$3"
__val="$4"
__end="$5"
if [ -z "$__opt" ]; then
_usage usage: _setopt '"file" "opt" "=" "value" [";"]'
return
fi
if [ ! -f "$__conf" ]; then
touch "$__conf"
fi
if [ -n "$(_tail_c 1 <"$__conf")" ]; then
echo >>"$__conf"
fi
if grep -n "^$__opt$__sep" "$__conf" >/dev/null; then
if _contains "$__val" "&"; then
__val="$(echo "$__val" | sed 's/&/\\&/g')"
fi
if _contains "$__val" "|"; then
__val="$(echo "$__val" | sed 's/|/\\|/g')"
fi
text="$(cat "$__conf")"
printf -- "%s\n" "$text" | sed "s|^$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
elif grep -n "^#$__opt$__sep" "$__conf" >/dev/null; then
if _contains "$__val" "&"; then
__val="$(echo "$__val" | sed 's/&/\\&/g')"
fi
if _contains "$__val" "|"; then
__val="$(echo "$__val" | sed 's/|/\\|/g')"
fi
text="$(cat "$__conf")"
printf -- "%s\n" "$text" | sed "s|^#$__opt$__sep.*$|$__opt$__sep$__val$__end|" >"$__conf"
else
echo "$__opt$__sep$__val$__end" >>"$__conf"
fi
}
_install() {
_info "Installing $PROJECT_NAME."
_initpath
curl -s "$SCRIPT_URL" > "$PROJECT_ENTRY_BIN" && chmod +x "$PROJECT_ENTRY_BIN"
if [ -x "$PROJECT_ENTRY_BIN" ] ; then
_suc "Install $PROJECT_NAME complete."
else
_err "Install $PROJECT_NAME failed."
exit 4
fi
installcronjob
installAlais
}
installcronjob() {
_CRONTAB="crontab"
_t=$(_time)
random_minute=$(_math $_t % 60)
random_hour=$(_math $_t % 9 + 9 ) # 9 ~ 17
if ! _exists "$_CRONTAB" ; then
_err "$_CRONTAB not exits\ncrontab定时任务不存在,请安装。参考文档:https://httpsok.com/doc/faq/crontab.html \n"
return 4
fi
if ! $_CRONTAB -l | grep "$PROJECT_ENTRY" > /dev/null; then
_info "Installing cron job."
if _exists uname && uname -a | grep SunOS >/dev/null; then
_CRONTAB_STDIN="$_CRONTAB --"
else
_CRONTAB_STDIN="$_CRONTAB -"
fi
$_CRONTAB -l | {
cat
echo "$random_minute $random_hour * * * '$PROJECT_ENTRY_BIN' -m -r >> '$PROJECT_LOG_FILE' 2>&1"
} | $_CRONTAB_STDIN
_suc "Install cron job complete."
fi
if [ "$?" != "0" ]; then
_err "Install cron job failed. You can add cronjob by yourself."
_err "Or you can add cronjob by yourself:"
_err "$random_minute $random_hour * * * '$PROJECT_ENTRY_BIN' -m -r >> '$PROJECT_LOG_FILE' 2>&1"
return 1
fi
}
installAlais() {
_envfile="$PROJECT_ENTRY_BIN.env"
echo "alias $PROJECT_ENTRY=\"$PROJECT_ENTRY_BIN\"" > "$_envfile"
_info "Installing alias"
_profile="$(_detect_profile)"
if [ "$_profile" ]; then
_info "Found profile: $_profile"
_info "Installing alias to '$_profile'"
_setopt "$_profile" ". \"$_envfile\""
_suc "OK, Close and reopen your terminal to start using $PROJECT_NAME"
else
_err "No profile is found, you will need to go into $PROJECT_HOME to use $PROJECT_NAME"
fi
}
_uninstall() {
_info "Uninstalling httpsok."
_remote_uninstall
uninstallcronjob
_uninstallalias
if [ -d "$PROJECT_HOME" ]; then
_info "Removing directory $PROJECT_HOME"
rm -rf "$PROJECT_HOME"
fi
_suc "Uninstall httpsok complete."
showWelcome
echo "If your need install httpsok agian. Please see $HTTPSOK_HOME_URL .
curl -s $SCRIPT_URL | bash -s 'your token'
"
}
_uninstallalias() {
_envfile="$PROJECT_ENTRY_BIN.env"
_profile="$(_detect_profile)"
if [ "$_profile" ]; then
_info "Uninstalling alias from: '$_profile'"
text="$(cat "$_profile")"
echo "$text" | sed "s|^.*\"$_envfile\"$||" >"$_profile"
fi
}
uninstallcronjob() {
_CRONTAB="crontab"
if ! _exists "$_CRONTAB" ; then
_err "$_CRONTAB not exits"
return 4
fi
cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY")"
if [ "$cr" ]; then
_info "Removing cron job"
if _exists uname && uname -a | grep SunOS >/dev/null; then
$_CRONTAB -l | sed "/$PROJECT_ENTRY/d" | $_CRONTAB --
else
$_CRONTAB -l | sed "/$PROJECT_ENTRY/d" | $_CRONTAB -
fi
_suc "Remove cron job complete."
fi
}
_run() {
_load_token
_check_token
if ! _preparse ; then
_err "No SSL certificate was detected(未检测到SSL证书).\n "
_info "Please refer to resolve the issue(查看文档,解决此问题). https://httpsok.com/doc/faq/nossl.html "
echo ""
return 4
fi
_info "Checking SSL certificate, please wait a moment(证书检测中请稍等...)."
echo
_upload_certs
_check_dns
_check_certs
_reload_nginx
_done
echo ""
}
_process() {
while [ ${#} -gt 0 ]; do
case "${1}" in
--help | -h)
show_help
return
;;
--version | -v)
version
return
;;
--run | -r)
_run
;;
--setup | -s)
_save_token "$2"
_install
_run
return
;;
--token | -t)
if [ "$2" ]; then
_save_token "$2"
else
_show_token
fi
return
;;
--mode | -m)
MODE="crontab"
;;
--install | -i)
_install
return
;;
--uninstall | -u)
_uninstall
return
;;
*)
echo "Unknown parameter : $1 $2"
return 1
;;
esac
shift 1
done
}
show_help() {
echo "Usage: $PROJECT_ENTRY <command> ... [parameters ...]
Commands:
-h, --help Show this help message.
-v, --version Show version info.
-r, --run Run the $PROJECT_NAME
-s, --setup Install and run (Recommend first time use it).
-t, --token Set or show the token.
-m, --mode Mode of normal or crontab.
-i, --install Install $PROJECT_NAME to your system.
-u, --uninstall Uninstall $PROJECT_NAME in your system.
"
showWelcome
}
main() {
[ -z "$1" ] && show_help && return
if _startswith "$1" '-'; then _process "$@"; else _process --setup "$@"; fi
}
main "$@"
正文到此结束