diff --git a/README.md b/README.md index 6dbd261..90da025 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ - [参数详解](#参数详解) - [举例](#举例) - [Alist](#alist) + - [Rclone](#rclone) + - [Calibre](#calibre) - [LianHuanHua](#lianhuanhua) - [Dev](#dev) @@ -54,6 +56,7 @@ wget https://woniuzfb.github.io/iptv/nx.sh && bash nx.sh - postfix - mmproxy - dnscrypt proxy +- iperf3 --- @@ -257,6 +260,26 @@ wget https://woniuzfb.github.io/iptv/iptv.sh && bash iptv.sh ./debug ali ``` +## Rclone + +```bash +./debug rc +``` + +- remote +- mount +- serve +- sync + +## Calibre + +```bash +./debug cw +``` + +- calibre-web +- kcc + ## LianHuanHua ```bash diff --git a/build b/build index 6e012a2..0544ac3 100644 --- a/build +++ b/build @@ -11,7 +11,7 @@ ReplaceInclude() echo "${2:-}if [ \"\$self\" == \"tv\" ] || [ \"\$self\" == \"iptv\" ]" echo "${2:-}then" ReplaceInclude src/tv " ${2:-}" - bins=(v2 x nx or pve arm ibm cf cx ali lhh) + bins=(v2 x nx or pve arm ibm cf cx ali lhh rc cw) for bin in "${bins[@]}" do echo "${2:-}elif [ \"\$self\" == \"$bin\" ]" @@ -31,11 +31,31 @@ ReplaceInclude() replace_name="${replace_name#*/}" done + local here=false here_tag="" while IFS= read -r line do + if [ "$here" = true ] + then + echo "$line" + if [ "$line" = "$here_tag" ] + then + here=false + fi + continue + elif [[ $line =~ ^([ ]*)cat([ ]) ]] + then + here=true + here_tag="${line#*<<}" + here_tag="${here_tag#"${here_tag%%[![:space:]]*}"}" + here_tag=${here_tag%% *} + here_tag=${here_tag#-} + fi if [ -z "$line" ] then echo + elif [ "$here" = true ] + then + echo "$line" elif [[ $line =~ ^([ ]*)Include\ ([^ ]+) ]] then ReplaceInclude ${BASH_REMATCH[2]} "${2:-}${BASH_REMATCH[1]}" diff --git a/core b/core index 8ee0b0b..8af0639 100644 --- a/core +++ b/core @@ -13,29 +13,42 @@ Trim() JoinByChar() { - local IFS="$1" - shift - echo "$*" + local IFS="$1" + shift + echo "$*" } JoinByString() { - local separator="$1" - shift - local first="$1" - shift - printf "%s" "$first" "${@/#/$separator}" + local separator="$1" + shift + local first="$1" + shift + printf "%s" "$first" "${@/#/$separator}" +} + +ToJsonArray() +{ + local var=("$1"[@]) + if [[ -z "${!var:-}" ]] + then + echo "[]" + return 0 + fi + local arr=("${!var}") + local json_array=$(printf '%s\n' "${arr[@]}" | $JQ_FILE -R . | $JQ_FILE -s .) + echo $json_array } shopt -s extglob EleInArray() { - local ele="$1" - shift - local var=("$1"[@]) - local arr=("${!var}") - [[ "$ele" == @($(JoinByChar '|' "${arr[@]//|/\\|}")) ]] + local ele="$1" + shift + local var=("$1"[@]) + local arr=("${!var}") + [[ "$ele" == @($(JoinByChar '|' "${arr[@]//|/\\|}")) ]] } printf() @@ -197,6 +210,16 @@ GetRandomMac() echo $RANDOM|md5sum|sed 's/../&:/g'|cut -c 1-17 } +RemoveQuotes() +{ + local text="${!1}" + if [[ "$text" =~ ^\"(.*)\"$ ]] || [[ "$text" =~ ^\'(.*)\'$ ]] + then + text="${BASH_REMATCH[1]}" + read -r ${1} <<< "$text" + fi +} + PrepTerm() { unset term_child_pid diff --git a/docs/iptv.sh b/docs/iptv.sh index b85ec62..7bab340 100755 --- a/docs/iptv.sh +++ b/docs/iptv.sh @@ -34,6 +34,7 @@ IP_DENY="$IPTV_ROOT/ip.deny" IP_LOG="$IPTV_ROOT/ip.log" FFMPEG_LOG_ROOT="$IPTV_ROOT/ffmpeg" # create your own mirror: tv ffmpeg +BACKUP_ROOT="$HOME"/iptv_sh_backup FFMPEG_MIRROR_LINK="http://pngquant.com/ffmpeg" V2_FILE="/usr/local/bin/v2" V2_LINK="https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh" @@ -41,6 +42,7 @@ V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" V2CTL_FILE="/usr/local/bin/v2ctl" V2_CONFIG="/usr/local/etc/v2ray/config.json" X_FILE="/usr/local/bin/x" +X_CONFIG="/usr/local/etc/xray/config.json" FFMPEG_MIRROR_ROOT="$IPTV_ROOT/ffmpeg" LIVE_ROOT="$IPTV_ROOT/live" SERVICES_FILE="$IPTV_ROOT/services.json" @@ -136,10 +138,10 @@ ArchCheck() if grep -Eqi "x86_64|amd64" <<< "$arch" then arch="x86_64" - elif grep -Eqi "i386|i686" <<< "$arch" + elif grep -Eqi "i386|i686|x86" <<< "$arch" then arch="i386" - elif grep -Eqi "aarch64|armv8" <<< "$arch" + elif grep -Eqi "aarch64|armv8|arm64" <<< "$arch" then arch="arm64" elif grep -qi "armv7" <<< "$arch" @@ -800,9 +802,9 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - if [ -n "${checkbox_pages_tip:-}" ] + if [ -n "${pages_tip:-}" ] then - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" fi tput cud $((current_index+1)) first_keystroke=false @@ -814,12 +816,12 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" tput cud $((current_index+1)) } inquirer:on_checkbox_input_up() { - if [ "$checkbox_input_search" = true ] + if [ "$input_search" = true ] then tput cub "$(tput cols)" tput el @@ -833,29 +835,29 @@ inquirer() local i - for((i=0;i 选择, 确认)\"`${normal}\n\n\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n\n\n" fi inquirer:on_checkbox_input_up return fi - if [ "$checkbox_input_page" = true ] + if [ "$input_page" = true ] then - checkbox_input_page=false - if [ -n "${checkbox_input_page_num:-}" ] + input_page=false + if [ -n "${input_page_num:-}" ] then - if [ "$checkbox_input_page_num" -gt "$checkbox_pages_count" ] || [ "$checkbox_input_page_num" -eq $((checkbox_pages_index+1)) ] + if [ "$input_page_num" -gt "$pages_count" ] || [ "$input_page_num" -eq $((pages_index+1)) ] then - checkbox_input_page_num="" + input_page_num="" return fi - checkbox_pages_index=$((checkbox_input_page_num-1)) + pages_index=$((input_page_num-1)) - checkbox_pages_tip="${dim}$checkbox_pages_arrows $((checkbox_pages_index+1))/$checkbox_pages_count `gettext \"页\"`${normal}" + pages_tip="${dim}$pages_arrows $((pages_index+1))/$pages_count `gettext \"页\"`${normal}" - if [ "$checkbox_input_page_num" -eq "$checkbox_pages_count" ] + if [ "$input_page_num" -eq "$pages_count" ] then - checkbox_page_list_count=$((checkbox_list_count-checkbox_pages_index*checkbox_list_perpage)) + page_list_count=$((list_count-pages_index*list_perpage)) else - checkbox_page_list_count=$checkbox_list_perpage + page_list_count=$list_perpage fi inquirer:page_instructions tput cub "$(tput cols)" - tput cud $((checkbox_list_perpage-current_index+1)) + tput cud $((list_perpage-current_index+1)) - for((i=0;i<=checkbox_list_perpage;i++)); + for((i=0;i<=list_perpage;i++)); do tput el tput cuu1 @@ -1215,71 +1218,71 @@ inquirer() tput el - if [ "$current_index" -gt "$checkbox_page_list_count" ] + if [ "$current_index" -gt "$page_list_count" ] then - current_index=$checkbox_page_list_count + current_index=$page_list_count fi - checkbox_page_list=() + page_list=() checkbox_page_selected=() checkbox_page_select_all=true - for((i=0;i 选择, 确认)\"`${normal}\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n" for i in "${!checkbox_list[@]}" do @@ -1520,7 +1523,7 @@ inquirer() else inquirer:print "${cyan}${arrow}${normal}${unchecked} ${checkbox_list[i]}\n" fi - elif [ "$checkbox_pages_count" -gt 1 ] && [ "$i" = "$checkbox_list_perpage" ] + elif [ "$pages_count" -gt 1 ] && [ "$i" = "$list_perpage" ] then break else @@ -1531,11 +1534,11 @@ inquirer() inquirer:print " ${unchecked} ${checkbox_list[i]}\n" fi fi - ((checkbox_page_list_count++)) - checkbox_page_list+=("${checkbox_list[i]}") + page_list_count=$((page_list_count+1)) + page_list+=("${checkbox_list[i]}") done - for((i=0;i> /etc/profile - fi + rm -rf /usr/local/go + tar -C /usr/local -xzf ~/$go_package } FFmpegInstall() @@ -9284,7 +9661,7 @@ InputChannelsIndex() continue 2 elif [[ $chnl_index_start -gt 0 ]] && [[ $chnl_index_end -le $chnls_count ]] && [[ $chnl_index_end -gt $chnl_index_start ]] then - ((chnl_index_start--)) + chnl_index_start=$((chnl_index_start-1)) for((i=chnl_index_start;i "$HOME"/update_cf_ibm_ip.sh < $nginx_prefix/conf/cloudflare_ip.conf; ibm_ips=( 50.22.0.0/16 @@ -31468,20 +31846,20 @@ ibm_ips=( 169.61.0.0/16 169.62.0.0/16 ) -for i in \"\${ibm_ips[@]}\"; do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; +for i in "\${ibm_ips[@]}"; do + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v4); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v6); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done echo >> $nginx_prefix/conf/cloudflare_ip.conf; echo '# use any of the following two' >> $nginx_prefix/conf/cloudflare_ip.conf; echo 'real_ip_header CF-Connecting-IP;' >> $nginx_prefix/conf/cloudflare_ip.conf; echo '#real_ip_header X-Forwarded-For;' >> $nginx_prefix/conf/cloudflare_ip.conf; -" > ~/update_cf_ibm_ip.sh +EOF bash ~/update_cf_ibm_ip.sh @@ -31502,7 +31880,8 @@ NginxDisableDomain() NginxAppendHttpConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectConf() { echo && read -p "输入网址: " http_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectToHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsRedirectConf() { echo && read -p "输入网址: " https_redirect_address - printf '%s' " server { - listen $server_https_port; +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsRedirectConf() { echo && read -p "输入网址: " http_https_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAddDomain() @@ -31924,7 +32309,7 @@ ResourceLimit() then if [ ! -e ~/.bash_profile ] || ! grep -q ulimit < ~/.bash_profile then -cat >> ~/.bash_profile << EOF +cat >> ~/.bash_profile <> ~/.profile << EOF +cat >> ~/.profile < /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case $* in + "e") + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " openresty 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -48851,7 +49269,8 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then ResourceLimit - echo "[Unit] +cat > /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case ${1:-} in + e) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + l) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_logs=("$nginx_prefix"/logs/*) + shopt -u nullglob + + if [ -z "${nginx_logs:-}" ] + then + Println "$error 没有日志 !\n" + exit 1 + fi + + echo + inquirer list_input_index "选择日志文件" nginx_logs nginx_logs_index + + if [ "${2:-}" == "t" ] + then + tail -f "${nginx_logs[nginx_logs_index]}" + exit 0 + fi + editor "${nginx_logs[nginx_logs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " nginx 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -49039,24 +49516,12 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service echo -en "0.0.0.0/0\n::/0\n" > ~/allowed-subnets.txt fi + GoInstall + if [[ ! -x "$HOME/go/bin/go-mmproxy" ]] then Println "$info 安装 go-mmproxy" - - GoInstall - go get github.com/path-network/go-mmproxy - - if [[ ! -x $(command -v go-mmproxy) ]] - then - export PATH="$PATH:$HOME/go/bin" - DistCheck - if [ "$dist" == "rpm" ] - then - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.bash_profile - else - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.profile - fi - fi + go install github.com/path-network/go-mmproxy@latest fi echo @@ -49096,7 +49561,10 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service if [ "$mmproxy_name" == "ssh" ] then - Println "$tip 请确保已经设置 ssh 监听地址和端口" + Println "$tip 请之后将 nginx 分流 ssh 协议至 $mmproxy_listen, 并将 ssh 监听改为下面输入的地址和端口" + elif [ "$mmproxy_name" == "acme" ] + then + Println "$tip 请之后将 nginx 分流 acme 协议至 $mmproxy_listen" fi Println "$tip 比如: 127.0.0.1:2222" @@ -49110,19 +49578,22 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service reload=1 fi - echo "[Unit] +cat > /etc/systemd/system/mmproxy-"$mmproxy_name".service < "/etc/systemd/system/mmproxy-$mmproxy_name.service" +WantedBy=multi-user.target +EOF if [ "${reload:-0}" -eq 1 ] then @@ -49136,18 +49607,22 @@ WantedBy=multi-user.target" > "/etc/systemd/system/mmproxy-$mmproxy_name.service if [ ! -f ~/ip.sh ] then - echo "#!/bin/bash +cat > "$HOME"/ip.sh < ~/ip.sh +ip -6 route add local ::/0 dev lo table 100 +EOF chmod +x ~/ip.sh fi if [ ! -f /etc/rc.local ] then - echo "#!/bin/bash -$HOME/ip.sh" > /etc/rc.local +cat > /etc/rc.local <> /etc/rc.local @@ -49158,10 +49633,11 @@ $HOME/ip.sh" > /etc/rc.local if [[ $(systemctl is-active rc-local) == "inactive" ]] then systemctl enable rc-local || true - if ! grep -q 'iif lo lookup 100' < <(ip rule list) - then - systemctl start rc-local || true - fi + fi + + if ! grep -q 'iif lo lookup 100' < <(ip rule list) + then + systemctl restart rc-local || true fi Println "$info mmproxy-$mmproxy_name 设置成功\n" @@ -49364,7 +49840,7 @@ then V2_LINK="https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh" V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xray_install-release.sh" V2CTL_FILE="/usr/local/bin/xray" - V2_CONFIG="/usr/local/etc/xray/config.json" + V2_CONFIG="$X_CONFIG" elif [ -d /etc/v2ray/ ] then systemctl disable v2ray --now > /dev/null 2> /dev/null || true @@ -52421,6 +52897,13 @@ then Println "$error jq.json 下载出错, 无法连接 github ?" fi + if curl -s -L "https://api.github.com/repos/alist-org/alist/releases/latest" -o "$FFMPEG_MIRROR_ROOT/alist.json_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/alist.json_tmp" "$FFMPEG_MIRROR_ROOT/alist.json" + else + Println "$error alist.json 下载出错, 无法连接 github ?" + fi + if curl -s -L "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" -o "$FFMPEG_MIRROR_ROOT/v2ray.json_tmp" then mv "$FFMPEG_MIRROR_ROOT/v2ray.json_tmp" "$FFMPEG_MIRROR_ROOT/v2ray.json" @@ -52840,6 +53323,213 @@ then fi exit 0 ;; + b|backup) + # --exclude=exclude_before --include=src/ --include=src/xxx/*** --exclude=src/*** --exclude=exclude_after + + IPTV_ROOT="${IPTV_ROOT%/}" + FFMPEG_MIRROR_ROOT="${FFMPEG_MIRROR_ROOT%/}" + LIVE_ROOT="${LIVE_ROOT%/}" + NODE_ROOT="${NODE_ROOT%/}" + + iptv_source="$IPTV_ROOT" + + iptv_excludes_before=( + /c/ + /ffmpeg-git-'*' + /vip/ + node_modules/ + ) + + ffmpeg_excludes_before=( + /Amlogic_s905-kernel-master.zip + /builds/ + /calibre/ + /dnscrypt/ + /ffmpeg_c + /fontforge-20190413.tar.gz + /imgcat.zip + /jq-'*' + /releases/ + /v2ray/ + /xray/ + '*'.ipk + '*'.err + '*'.log + '*'.pid + ) + + if [[ "$FFMPEG_MIRROR_ROOT" =~ "$iptv_source"(.*) ]] + then + relative_path="${BASH_REMATCH[1]:-}" + relative_path="${relative_path#/}" + if [ -n "$relative_path" ] + then + for i in "${!ffmpeg_excludes_before[@]}" + do + if [[ "${ffmpeg_excludes_before[i]}" == /* ]] + then + ffmpeg_excludes_before[i]="/${relative_path}${ffmpeg_excludes_before[i]}" + else + ffmpeg_excludes_before[i]="/$relative_path/${ffmpeg_excludes_before[i]}" + fi + done + fi + iptv_excludes_before+=("${ffmpeg_excludes_before[@]}") + else + ffmpeg_source="$FFMPEG_MIRROR_ROOT" + fi + + if [[ "$LIVE_ROOT" =~ "$IPTV_ROOT"(.+) ]] + then + iptv_excludes_before+=("${BASH_REMATCH[1]}") + fi + + node_excludes_before=( + node_modules/ + ) + + if ! [[ "$NODE_ROOT" =~ "$IPTV_ROOT"(.*) ]] + then + node_source="$NODE_ROOT" + fi + + nginx_source=/usr/local/nginx + + nginx_excludes_before=( + /logs/'*'.gz + node_modules/ + ) + + nginx_includes=( + /conf/'***' + /html/'***' + /logs/'***' + ) + + nginx_excludes_after=( + /'***' + ) + + openresty_source=/usr/local/openresty + + openresty_excludes_before=( + /nginx/logs/'*'.gz + node_modules/ + ) + + openresty_includes=( + /nginx/ + /nginx/conf/'***' + /nginx/html/'***' + /nginx/logs/'***' + /nginx/lua/'***' + ) + + openresty_excludes_after=( + /'***' + ) + + v2ray_source="${V2_CONFIG%/*}" + + xray_source="${X_CONFIG%/*}" + + DistCheck + + if [ "$dist" == "mac" ] + then + systemd_source="$HOME"/Library/LaunchAgents + else + systemd_source=/etc/systemd/system + fi + + systemd_includes=( + /alist.service + /aria2.service + /dnscrypt-proxy.service + /mmproxy-'*'.service + /nginx.service + /openresty.service + /v2ray.service + /xray.service + /aios.'*'.service + /com.aios.'*'.plist + ) + + systemd_excludes_after=( + /'***' + ) + + home_source="$HOME" + + home_includes=( + /.bash_history + ) + + home_excludes_after=( + /'***' + ) + + DepInstall rsync + + mkdir -p "$BACKUP_ROOT" + + for backup in iptv nginx openresty v2ray xray ffmpeg node systemd home + do + rsync_commands=() + source="${backup}_source" + + if [[ -z "${!source:-}" ]] + then + continue + fi + + source="${!source}" + + if [ ! -d "$source" ] + then + continue + fi + + excludes_before=("${backup}_excludes_before"[@]) + + if [[ -n "${!excludes_before:-}" ]] + then + excludes_before=("${!excludes_before}") + for exclude in "${excludes_before[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + includes=("${backup}_includes"[@]) + + if [[ -n "${!includes:-}" ]] + then + includes_arr=("${!includes}") + for include in "${includes_arr[@]}" + do + rsync_commands+=( --include="$include" ) + done + fi + + excludes_after=("${backup}_excludes_after"[@]) + + if [[ -n "${!excludes_after:-}" ]] + then + excludes_after=("${!excludes_after}") + for exclude in "${excludes_after[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + rsync -avP --safe-links --delete --delete-excluded ${rsync_commands[@]+"${rsync_commands[@]}"} "$source/" "$BACKUP_ROOT/$backup/" + done + + Println "$info 已创建备份 $BACKUP_ROOT\n" + + exit 0 + ;; *) ;; esac @@ -52855,7 +53545,7 @@ then Menu fi else - while getopts "i:l:P:o:p:S:t:s:c:v:a:f:d:q:b:r:k:K:m:n:z:H:T:L:CRe" flag + while getopts "i:l:P:o:p:S:t:s:c:v:a:f:d:q:b:r:k:K:m:n:z:H:T:L:CReh" flag do case "$flag" in i) stream_link="$OPTARG";; @@ -52885,7 +53575,7 @@ else H) flv_h265=true;; T) flv_push_link="$OPTARG";; L) flv_pull_link="$OPTARG";; - *) Usage; + h|*) Usage; esac done diff --git a/env b/env index c9d46f2..9a60849 100644 --- a/env +++ b/env @@ -32,6 +32,9 @@ FFMPEG_FILE=/usr/local/bin/ffmpeg FFPROBE_FILE=/usr/local/bin/ffprobe CURL_IMPERSONATE_FILE=/usr/local/bin/curl-impersonate +# backup +BACKUP_ROOT="$HOME"/iptv_sh_backup + # FFmpeg FFMPEG_ROOT="$HOME" @@ -54,7 +57,6 @@ XTREAM_CODES_EXAM="$IPTV_ROOT"/xtream_codes_exam IP_DENY="$IPTV_ROOT"/ip.deny IP_LOG="$IPTV_ROOT"/ip.log LIVE_ROOT="$IPTV_ROOT"/live -SERVICES_FILE="$IPTV_ROOT"/services.json VIP_FILE="$IPTV_ROOT"/vip.json VIP_CHANNELS_LINK="$FFMPEG_MIRROR_LINK"/vip_channels.json VIP_CHANNELS_FILE="$IPTV_ROOT"/vip_channels.json @@ -80,6 +82,7 @@ V2_CONFIG=/usr/local/etc/v2ray/config.json # xray X_FILE=/usr/local/bin/x +X_CONFIG=/usr/local/etc/xray/config.json # cloudflare CF_FILE=/usr/local/bin/cf @@ -98,8 +101,29 @@ IBM_FILE=/usr/local/bin/ibm IBM_APPS_ROOT="$HOME"/ibm_apps IBM_CONFIG="$HOME"/ibm.json +# Services +SERVICES_ROOT="$HOME"/iptv_sh_services +SERVICES_CONFIG="$SERVICES_ROOT"/config.json + # Alist ALIST_FILE=/usr/local/bin/ali +ALIST_ROOT="$SERVICES_ROOT"/alist +ALIST_LINK=https://github.com/alist-org/alist +ALIST_LINK_FALLBACK="$FFMPEG_MIRROR_LINK"/alist # LianHuanHua LIANHUANHUA_FILE=/usr/local/bin/lhh +LIANHUANHUA_ROOT="$SERVICES_ROOT"/lianhuanhua +LIANHUANHUA_CONFIG="$LIANHUANHUA_ROOT"/config.json + +# Rclone +RCLONE_FILE=/usr/local/bin/rc +RCLONE_ROOT="$SERVICES_ROOT"/rclone + +# Calibre +CALIBRE_FILE=/usr/local/bin/cw +CALIBRE_ROOT="$SERVICES_ROOT"/calibre + +# Kcc +KCC_ROOT="$CALIBRE_ROOT"/kcc +KCC_FILE="$KCC_ROOT"/kcc-c2e.py diff --git a/iptv.sh b/iptv.sh index b85ec62..7bab340 100755 --- a/iptv.sh +++ b/iptv.sh @@ -34,6 +34,7 @@ IP_DENY="$IPTV_ROOT/ip.deny" IP_LOG="$IPTV_ROOT/ip.log" FFMPEG_LOG_ROOT="$IPTV_ROOT/ffmpeg" # create your own mirror: tv ffmpeg +BACKUP_ROOT="$HOME"/iptv_sh_backup FFMPEG_MIRROR_LINK="http://pngquant.com/ffmpeg" V2_FILE="/usr/local/bin/v2" V2_LINK="https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh" @@ -41,6 +42,7 @@ V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh" V2CTL_FILE="/usr/local/bin/v2ctl" V2_CONFIG="/usr/local/etc/v2ray/config.json" X_FILE="/usr/local/bin/x" +X_CONFIG="/usr/local/etc/xray/config.json" FFMPEG_MIRROR_ROOT="$IPTV_ROOT/ffmpeg" LIVE_ROOT="$IPTV_ROOT/live" SERVICES_FILE="$IPTV_ROOT/services.json" @@ -136,10 +138,10 @@ ArchCheck() if grep -Eqi "x86_64|amd64" <<< "$arch" then arch="x86_64" - elif grep -Eqi "i386|i686" <<< "$arch" + elif grep -Eqi "i386|i686|x86" <<< "$arch" then arch="i386" - elif grep -Eqi "aarch64|armv8" <<< "$arch" + elif grep -Eqi "aarch64|armv8|arm64" <<< "$arch" then arch="arm64" elif grep -qi "armv7" <<< "$arch" @@ -800,9 +802,9 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - if [ -n "${checkbox_pages_tip:-}" ] + if [ -n "${pages_tip:-}" ] then - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" fi tput cud $((current_index+1)) first_keystroke=false @@ -814,12 +816,12 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" tput cud $((current_index+1)) } inquirer:on_checkbox_input_up() { - if [ "$checkbox_input_search" = true ] + if [ "$input_search" = true ] then tput cub "$(tput cols)" tput el @@ -833,29 +835,29 @@ inquirer() local i - for((i=0;i 选择, 确认)\"`${normal}\n\n\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n\n\n" fi inquirer:on_checkbox_input_up return fi - if [ "$checkbox_input_page" = true ] + if [ "$input_page" = true ] then - checkbox_input_page=false - if [ -n "${checkbox_input_page_num:-}" ] + input_page=false + if [ -n "${input_page_num:-}" ] then - if [ "$checkbox_input_page_num" -gt "$checkbox_pages_count" ] || [ "$checkbox_input_page_num" -eq $((checkbox_pages_index+1)) ] + if [ "$input_page_num" -gt "$pages_count" ] || [ "$input_page_num" -eq $((pages_index+1)) ] then - checkbox_input_page_num="" + input_page_num="" return fi - checkbox_pages_index=$((checkbox_input_page_num-1)) + pages_index=$((input_page_num-1)) - checkbox_pages_tip="${dim}$checkbox_pages_arrows $((checkbox_pages_index+1))/$checkbox_pages_count `gettext \"页\"`${normal}" + pages_tip="${dim}$pages_arrows $((pages_index+1))/$pages_count `gettext \"页\"`${normal}" - if [ "$checkbox_input_page_num" -eq "$checkbox_pages_count" ] + if [ "$input_page_num" -eq "$pages_count" ] then - checkbox_page_list_count=$((checkbox_list_count-checkbox_pages_index*checkbox_list_perpage)) + page_list_count=$((list_count-pages_index*list_perpage)) else - checkbox_page_list_count=$checkbox_list_perpage + page_list_count=$list_perpage fi inquirer:page_instructions tput cub "$(tput cols)" - tput cud $((checkbox_list_perpage-current_index+1)) + tput cud $((list_perpage-current_index+1)) - for((i=0;i<=checkbox_list_perpage;i++)); + for((i=0;i<=list_perpage;i++)); do tput el tput cuu1 @@ -1215,71 +1218,71 @@ inquirer() tput el - if [ "$current_index" -gt "$checkbox_page_list_count" ] + if [ "$current_index" -gt "$page_list_count" ] then - current_index=$checkbox_page_list_count + current_index=$page_list_count fi - checkbox_page_list=() + page_list=() checkbox_page_selected=() checkbox_page_select_all=true - for((i=0;i 选择, 确认)\"`${normal}\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n" for i in "${!checkbox_list[@]}" do @@ -1520,7 +1523,7 @@ inquirer() else inquirer:print "${cyan}${arrow}${normal}${unchecked} ${checkbox_list[i]}\n" fi - elif [ "$checkbox_pages_count" -gt 1 ] && [ "$i" = "$checkbox_list_perpage" ] + elif [ "$pages_count" -gt 1 ] && [ "$i" = "$list_perpage" ] then break else @@ -1531,11 +1534,11 @@ inquirer() inquirer:print " ${unchecked} ${checkbox_list[i]}\n" fi fi - ((checkbox_page_list_count++)) - checkbox_page_list+=("${checkbox_list[i]}") + page_list_count=$((page_list_count+1)) + page_list+=("${checkbox_list[i]}") done - for((i=0;i> /etc/profile - fi + rm -rf /usr/local/go + tar -C /usr/local -xzf ~/$go_package } FFmpegInstall() @@ -9284,7 +9661,7 @@ InputChannelsIndex() continue 2 elif [[ $chnl_index_start -gt 0 ]] && [[ $chnl_index_end -le $chnls_count ]] && [[ $chnl_index_end -gt $chnl_index_start ]] then - ((chnl_index_start--)) + chnl_index_start=$((chnl_index_start-1)) for((i=chnl_index_start;i "$HOME"/update_cf_ibm_ip.sh < $nginx_prefix/conf/cloudflare_ip.conf; ibm_ips=( 50.22.0.0/16 @@ -31468,20 +31846,20 @@ ibm_ips=( 169.61.0.0/16 169.62.0.0/16 ) -for i in \"\${ibm_ips[@]}\"; do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; +for i in "\${ibm_ips[@]}"; do + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v4); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v6); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done echo >> $nginx_prefix/conf/cloudflare_ip.conf; echo '# use any of the following two' >> $nginx_prefix/conf/cloudflare_ip.conf; echo 'real_ip_header CF-Connecting-IP;' >> $nginx_prefix/conf/cloudflare_ip.conf; echo '#real_ip_header X-Forwarded-For;' >> $nginx_prefix/conf/cloudflare_ip.conf; -" > ~/update_cf_ibm_ip.sh +EOF bash ~/update_cf_ibm_ip.sh @@ -31502,7 +31880,8 @@ NginxDisableDomain() NginxAppendHttpConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectConf() { echo && read -p "输入网址: " http_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectToHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsRedirectConf() { echo && read -p "输入网址: " https_redirect_address - printf '%s' " server { - listen $server_https_port; +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsRedirectConf() { echo && read -p "输入网址: " http_https_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAddDomain() @@ -31924,7 +32309,7 @@ ResourceLimit() then if [ ! -e ~/.bash_profile ] || ! grep -q ulimit < ~/.bash_profile then -cat >> ~/.bash_profile << EOF +cat >> ~/.bash_profile <> ~/.profile << EOF +cat >> ~/.profile < /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case $* in + "e") + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " openresty 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -48851,7 +49269,8 @@ then if [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then ResourceLimit - echo "[Unit] +cat > /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case ${1:-} in + e) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + l) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_logs=("$nginx_prefix"/logs/*) + shopt -u nullglob + + if [ -z "${nginx_logs:-}" ] + then + Println "$error 没有日志 !\n" + exit 1 + fi + + echo + inquirer list_input_index "选择日志文件" nginx_logs nginx_logs_index + + if [ "${2:-}" == "t" ] + then + tail -f "${nginx_logs[nginx_logs_index]}" + exit 0 + fi + editor "${nginx_logs[nginx_logs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " nginx 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -49039,24 +49516,12 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service echo -en "0.0.0.0/0\n::/0\n" > ~/allowed-subnets.txt fi + GoInstall + if [[ ! -x "$HOME/go/bin/go-mmproxy" ]] then Println "$info 安装 go-mmproxy" - - GoInstall - go get github.com/path-network/go-mmproxy - - if [[ ! -x $(command -v go-mmproxy) ]] - then - export PATH="$PATH:$HOME/go/bin" - DistCheck - if [ "$dist" == "rpm" ] - then - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.bash_profile - else - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.profile - fi - fi + go install github.com/path-network/go-mmproxy@latest fi echo @@ -49096,7 +49561,10 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service if [ "$mmproxy_name" == "ssh" ] then - Println "$tip 请确保已经设置 ssh 监听地址和端口" + Println "$tip 请之后将 nginx 分流 ssh 协议至 $mmproxy_listen, 并将 ssh 监听改为下面输入的地址和端口" + elif [ "$mmproxy_name" == "acme" ] + then + Println "$tip 请之后将 nginx 分流 acme 协议至 $mmproxy_listen" fi Println "$tip 比如: 127.0.0.1:2222" @@ -49110,19 +49578,22 @@ WantedBy=multi-user.target" > /etc/systemd/system/$nginx_name.service reload=1 fi - echo "[Unit] +cat > /etc/systemd/system/mmproxy-"$mmproxy_name".service < "/etc/systemd/system/mmproxy-$mmproxy_name.service" +WantedBy=multi-user.target +EOF if [ "${reload:-0}" -eq 1 ] then @@ -49136,18 +49607,22 @@ WantedBy=multi-user.target" > "/etc/systemd/system/mmproxy-$mmproxy_name.service if [ ! -f ~/ip.sh ] then - echo "#!/bin/bash +cat > "$HOME"/ip.sh < ~/ip.sh +ip -6 route add local ::/0 dev lo table 100 +EOF chmod +x ~/ip.sh fi if [ ! -f /etc/rc.local ] then - echo "#!/bin/bash -$HOME/ip.sh" > /etc/rc.local +cat > /etc/rc.local <> /etc/rc.local @@ -49158,10 +49633,11 @@ $HOME/ip.sh" > /etc/rc.local if [[ $(systemctl is-active rc-local) == "inactive" ]] then systemctl enable rc-local || true - if ! grep -q 'iif lo lookup 100' < <(ip rule list) - then - systemctl start rc-local || true - fi + fi + + if ! grep -q 'iif lo lookup 100' < <(ip rule list) + then + systemctl restart rc-local || true fi Println "$info mmproxy-$mmproxy_name 设置成功\n" @@ -49364,7 +49840,7 @@ then V2_LINK="https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh" V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xray_install-release.sh" V2CTL_FILE="/usr/local/bin/xray" - V2_CONFIG="/usr/local/etc/xray/config.json" + V2_CONFIG="$X_CONFIG" elif [ -d /etc/v2ray/ ] then systemctl disable v2ray --now > /dev/null 2> /dev/null || true @@ -52421,6 +52897,13 @@ then Println "$error jq.json 下载出错, 无法连接 github ?" fi + if curl -s -L "https://api.github.com/repos/alist-org/alist/releases/latest" -o "$FFMPEG_MIRROR_ROOT/alist.json_tmp" + then + mv "$FFMPEG_MIRROR_ROOT/alist.json_tmp" "$FFMPEG_MIRROR_ROOT/alist.json" + else + Println "$error alist.json 下载出错, 无法连接 github ?" + fi + if curl -s -L "https://api.github.com/repos/v2fly/v2ray-core/releases/latest" -o "$FFMPEG_MIRROR_ROOT/v2ray.json_tmp" then mv "$FFMPEG_MIRROR_ROOT/v2ray.json_tmp" "$FFMPEG_MIRROR_ROOT/v2ray.json" @@ -52840,6 +53323,213 @@ then fi exit 0 ;; + b|backup) + # --exclude=exclude_before --include=src/ --include=src/xxx/*** --exclude=src/*** --exclude=exclude_after + + IPTV_ROOT="${IPTV_ROOT%/}" + FFMPEG_MIRROR_ROOT="${FFMPEG_MIRROR_ROOT%/}" + LIVE_ROOT="${LIVE_ROOT%/}" + NODE_ROOT="${NODE_ROOT%/}" + + iptv_source="$IPTV_ROOT" + + iptv_excludes_before=( + /c/ + /ffmpeg-git-'*' + /vip/ + node_modules/ + ) + + ffmpeg_excludes_before=( + /Amlogic_s905-kernel-master.zip + /builds/ + /calibre/ + /dnscrypt/ + /ffmpeg_c + /fontforge-20190413.tar.gz + /imgcat.zip + /jq-'*' + /releases/ + /v2ray/ + /xray/ + '*'.ipk + '*'.err + '*'.log + '*'.pid + ) + + if [[ "$FFMPEG_MIRROR_ROOT" =~ "$iptv_source"(.*) ]] + then + relative_path="${BASH_REMATCH[1]:-}" + relative_path="${relative_path#/}" + if [ -n "$relative_path" ] + then + for i in "${!ffmpeg_excludes_before[@]}" + do + if [[ "${ffmpeg_excludes_before[i]}" == /* ]] + then + ffmpeg_excludes_before[i]="/${relative_path}${ffmpeg_excludes_before[i]}" + else + ffmpeg_excludes_before[i]="/$relative_path/${ffmpeg_excludes_before[i]}" + fi + done + fi + iptv_excludes_before+=("${ffmpeg_excludes_before[@]}") + else + ffmpeg_source="$FFMPEG_MIRROR_ROOT" + fi + + if [[ "$LIVE_ROOT" =~ "$IPTV_ROOT"(.+) ]] + then + iptv_excludes_before+=("${BASH_REMATCH[1]}") + fi + + node_excludes_before=( + node_modules/ + ) + + if ! [[ "$NODE_ROOT" =~ "$IPTV_ROOT"(.*) ]] + then + node_source="$NODE_ROOT" + fi + + nginx_source=/usr/local/nginx + + nginx_excludes_before=( + /logs/'*'.gz + node_modules/ + ) + + nginx_includes=( + /conf/'***' + /html/'***' + /logs/'***' + ) + + nginx_excludes_after=( + /'***' + ) + + openresty_source=/usr/local/openresty + + openresty_excludes_before=( + /nginx/logs/'*'.gz + node_modules/ + ) + + openresty_includes=( + /nginx/ + /nginx/conf/'***' + /nginx/html/'***' + /nginx/logs/'***' + /nginx/lua/'***' + ) + + openresty_excludes_after=( + /'***' + ) + + v2ray_source="${V2_CONFIG%/*}" + + xray_source="${X_CONFIG%/*}" + + DistCheck + + if [ "$dist" == "mac" ] + then + systemd_source="$HOME"/Library/LaunchAgents + else + systemd_source=/etc/systemd/system + fi + + systemd_includes=( + /alist.service + /aria2.service + /dnscrypt-proxy.service + /mmproxy-'*'.service + /nginx.service + /openresty.service + /v2ray.service + /xray.service + /aios.'*'.service + /com.aios.'*'.plist + ) + + systemd_excludes_after=( + /'***' + ) + + home_source="$HOME" + + home_includes=( + /.bash_history + ) + + home_excludes_after=( + /'***' + ) + + DepInstall rsync + + mkdir -p "$BACKUP_ROOT" + + for backup in iptv nginx openresty v2ray xray ffmpeg node systemd home + do + rsync_commands=() + source="${backup}_source" + + if [[ -z "${!source:-}" ]] + then + continue + fi + + source="${!source}" + + if [ ! -d "$source" ] + then + continue + fi + + excludes_before=("${backup}_excludes_before"[@]) + + if [[ -n "${!excludes_before:-}" ]] + then + excludes_before=("${!excludes_before}") + for exclude in "${excludes_before[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + includes=("${backup}_includes"[@]) + + if [[ -n "${!includes:-}" ]] + then + includes_arr=("${!includes}") + for include in "${includes_arr[@]}" + do + rsync_commands+=( --include="$include" ) + done + fi + + excludes_after=("${backup}_excludes_after"[@]) + + if [[ -n "${!excludes_after:-}" ]] + then + excludes_after=("${!excludes_after}") + for exclude in "${excludes_after[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + rsync -avP --safe-links --delete --delete-excluded ${rsync_commands[@]+"${rsync_commands[@]}"} "$source/" "$BACKUP_ROOT/$backup/" + done + + Println "$info 已创建备份 $BACKUP_ROOT\n" + + exit 0 + ;; *) ;; esac @@ -52855,7 +53545,7 @@ then Menu fi else - while getopts "i:l:P:o:p:S:t:s:c:v:a:f:d:q:b:r:k:K:m:n:z:H:T:L:CRe" flag + while getopts "i:l:P:o:p:S:t:s:c:v:a:f:d:q:b:r:k:K:m:n:z:H:T:L:CReh" flag do case "$flag" in i) stream_link="$OPTARG";; @@ -52885,7 +53575,7 @@ else H) flv_h265=true;; T) flv_push_link="$OPTARG";; L) flv_pull_link="$OPTARG";; - *) Usage; + h|*) Usage; esac done diff --git a/make b/make index 25902b4..8caffc6 100755 --- a/make +++ b/make @@ -1,5 +1,5 @@ #!/bin/bash -# LianHuanHua / Alist / FFmpeg / Nginx / Openresty / V2ray / Xray / Cloudflare / IBM Cloud Foundry / Armbian / Proxmox VE / ... +# LianHuanHua / Rclone / Alist / Calibre / FFmpeg / Nginx / Openresty / V2ray / Xray / Cloudflare / IBM Cloud Foundry / Armbian / Proxmox VE / ... # Copyright (C) 2019-2024 # Released under GPL Version 3 License diff --git a/scripts/build.sh b/scripts/build.sh index ead94b7..ecd5d60 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -15,17 +15,6 @@ Println() inquirer() { - if [[ ! -x $(command -v tput) ]] - then - if apt-get -y install ncurses-bin >/dev/null 2>&1 - then - Println "$info 依赖 tput 安装成功..." - else - Println "$error 依赖 tput 安装失败..." - exit 1 - fi - fi - inquirer:print() { tput el printf '%b' "$1" @@ -147,9 +136,9 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - if [ -n "${checkbox_pages_tip:-}" ] + if [ -n "${pages_tip:-}" ] then - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" fi tput cud $((current_index+1)) first_keystroke=false @@ -161,12 +150,12 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" tput cud $((current_index+1)) } inquirer:on_checkbox_input_up() { - if [ "$checkbox_input_search" = true ] + if [ "$input_search" = true ] then tput cub "$(tput cols)" tput el @@ -180,29 +169,29 @@ inquirer() local i - for((i=0;i 选择, 确认)\"`${normal}\n\n\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n\n\n" fi inquirer:on_checkbox_input_up return fi - if [ "$checkbox_input_page" = true ] + if [ "$input_page" = true ] then - checkbox_input_page=false - if [ -n "${checkbox_input_page_num:-}" ] + input_page=false + if [ -n "${input_page_num:-}" ] then - if [ "$checkbox_input_page_num" -gt "$checkbox_pages_count" ] || [ "$checkbox_input_page_num" -eq $((checkbox_pages_index+1)) ] + if [ "$input_page_num" -gt "$pages_count" ] || [ "$input_page_num" -eq $((pages_index+1)) ] then - checkbox_input_page_num="" + input_page_num="" return fi - checkbox_pages_index=$((checkbox_input_page_num-1)) + pages_index=$((input_page_num-1)) - checkbox_pages_tip="${dim}$checkbox_pages_arrows $((checkbox_pages_index+1))/$checkbox_pages_count `gettext \"页\"`${normal}" + pages_tip="${dim}$pages_arrows $((pages_index+1))/$pages_count `gettext \"页\"`${normal}" - if [ "$checkbox_input_page_num" -eq "$checkbox_pages_count" ] + if [ "$input_page_num" -eq "$pages_count" ] then - checkbox_page_list_count=$((checkbox_list_count-checkbox_pages_index*checkbox_list_perpage)) + page_list_count=$((list_count-pages_index*list_perpage)) else - checkbox_page_list_count=$checkbox_list_perpage + page_list_count=$list_perpage fi inquirer:page_instructions tput cub "$(tput cols)" - tput cud $((checkbox_list_perpage-current_index+1)) + tput cud $((list_perpage-current_index+1)) - for((i=0;i<=checkbox_list_perpage;i++)); + for((i=0;i<=list_perpage;i++)); do tput el tput cuu1 @@ -562,71 +552,71 @@ inquirer() tput el - if [ "$current_index" -gt "$checkbox_page_list_count" ] + if [ "$current_index" -gt "$page_list_count" ] then - current_index=$checkbox_page_list_count + current_index=$page_list_count fi - checkbox_page_list=() + page_list=() checkbox_page_selected=() checkbox_page_select_all=true - for((i=0;i 选择, 确认)\"`${normal}\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n" for i in "${!checkbox_list[@]}" do @@ -867,7 +857,7 @@ inquirer() else inquirer:print "${cyan}${arrow}${normal}${unchecked} ${checkbox_list[i]}\n" fi - elif [ "$checkbox_pages_count" -gt 1 ] && [ "$i" = "$checkbox_list_perpage" ] + elif [ "$pages_count" -gt 1 ] && [ "$i" = "$list_perpage" ] then break else @@ -878,11 +868,11 @@ inquirer() inquirer:print " ${unchecked} ${checkbox_list[i]}\n" fi fi - ((checkbox_page_list_count++)) - checkbox_page_list+=("${checkbox_list[i]}") + page_list_count=$((page_list_count+1)) + page_list+=("${checkbox_list[i]}") done - for((i=0;i "$HOME"/ffmpeg_build/lib/pkgconfig/libxml-2.0.pc < "$HOME/ffmpeg_build/lib/pkgconfig/libxml-2.0.pc" +EOF # libpng (for openjpeg) cd ~/ffmpeg_sources @@ -2441,7 +2791,8 @@ Cflags: -I\${includedir} make install mkdir -p "$HOME/ffmpeg_build/include/rubberband/" cp -f ../rubberband/* "$HOME/ffmpeg_build/include/rubberband/" - printf '%s' "prefix=$HOME/ffmpeg_build +cat > "$HOME"/ffmpeg_build/lib/pkgconfig/rubberband.pc < "$HOME/ffmpeg_build/lib/pkgconfig/rubberband.pc" +EOF # libsrt cd ~/ffmpeg_sources diff --git a/src/_4gtv/cron b/src/_4gtv/cron index cd320b6..5d2f04f 100644 --- a/src/_4gtv/cron +++ b/src/_4gtv/cron @@ -12,9 +12,9 @@ _4gtvCron() if [ "$result" = true ] then - if [ ! -s "$SERVICES_FILE" ] + if [ ! -s "$SERVICES_CONFIG" ] then - printf '{"%s":{"%s":[]}}' "4gtv" "accounts" > "$SERVICES_FILE" + printf '{"%s":{"%s":[]}}' "4gtv" "accounts" > "$SERVICES_CONFIG" fi new_acc=$( $JQ_FILE -n --arg email "$_4gtv_acc_email" --arg password "$_4gtv_acc_pass" \ @@ -24,7 +24,7 @@ _4gtvCron() }' ) jq_path='["4gtv","accounts"]' - JQ add "$SERVICES_FILE" "[$new_acc]" + JQ add "$SERVICES_CONFIG" "[$new_acc]" Println "$info 账号注册成功\n" else Println "$error 账号注册失败, 请重试\n\n$msg\n" @@ -34,11 +34,7 @@ _4gtvCron() IMG_FILE="$IPTV_ROOT/4gtv.png" - if [[ ! -x $(command -v convert) ]] - then - Println "$info 安装 ImageMagick" - ImageMagickInstall - fi + ImageMagickInstall for((i=0;i<5;i++)); do @@ -52,7 +48,6 @@ _4gtvCron() read -p "(默认: 刷新验证码): " validatecode [ -z "$validatecode" ] && continue else - Println "$info 尝试修复 magick ..." ImageMagickInstall rm -f "${IMG_FILE:-notfound}" fi @@ -79,7 +74,7 @@ _4gtvCron() map_string=true jq_path='["4gtv","accounts"]' jq_path2='["token"]' - JQ update "$SERVICES_FILE" email "$_4gtv_acc_email" "$token" + JQ update "$SERVICES_CONFIG" email "$_4gtv_acc_email" "$token" Println "$info 账号登录成功" Println "$info 验证账号..." @@ -102,7 +97,7 @@ _4gtvCron() fi done Println "$info 账号验证成功" - Println "$info 开启 7 天豪华套餐" + Println "$info 开启 30 天豪华套餐" IFS="^" read -r result msg < <(CurlFake -s -Lm 20 \ -H 'Origin: https://www.4gtv.tv' \ @@ -114,8 +109,8 @@ _4gtvCron() if [ "$result" = true ] then - Println "$info 7 天豪华套餐开启成功\n" + Println "$info 30 天豪华套餐开启成功\n" else - Println "$error 开启 7 天豪华套餐发生错误, 请重试\n\n$msg\n" + Println "$error 开启 30 天豪华套餐发生错误, 请重试\n\n$msg\n" fi } diff --git a/src/_4gtv/del_acc b/src/_4gtv/del_acc index 910c478..4b8c760 100644 --- a/src/_4gtv/del_acc +++ b/src/_4gtv/del_acc @@ -22,7 +22,7 @@ Del4gtvAcc() then _4gtv_accs_index=$((_4gtv_accs_num-1)) jq_path='["4gtv","accounts",'"$_4gtv_accs_index"']' - JQ delete "$SERVICES_FILE" + JQ delete "$SERVICES_CONFIG" Println "$info 账号删除成功\n" break else diff --git a/src/_4gtv/edit_acc b/src/_4gtv/edit_acc index a2fe6f8..6d639b3 100644 --- a/src/_4gtv/edit_acc +++ b/src/_4gtv/edit_acc @@ -32,7 +32,7 @@ Edit4gtvAcc() ) json=true jq_path='["4gtv","accounts",'"$_4gtv_accs_index"']' - JQ update "$SERVICES_FILE" "$new_acc" + JQ update "$SERVICES_CONFIG" "$new_acc" Println "$info 账号修改成功\n" break else diff --git a/src/_4gtv/list_accs b/src/_4gtv/list_accs index 92c246c..8827c0f 100644 --- a/src/_4gtv/list_accs +++ b/src/_4gtv/list_accs @@ -1,6 +1,6 @@ List4gtvAccs() { - GetServiceAccs 4gtv + ServiceGet 4gtv _4gtv_accs_list="" for((i=0;i<_4gtv_accs_count;i++)); diff --git a/src/_4gtv/login_acc b/src/_4gtv/login_acc index ba8cadd..fdae6ec 100644 --- a/src/_4gtv/login_acc +++ b/src/_4gtv/login_acc @@ -32,7 +32,7 @@ Login4gtvAcc() }' ) jq_path='["4gtv","accounts"]' - JQ add "$SERVICES_FILE" "[$new_acc]" + JQ add "$SERVICES_CONFIG" "[$new_acc]" Println "$info 账号添加成功\n" break ;; @@ -52,11 +52,7 @@ Login4gtvAcc() IMG_FILE="$IPTV_ROOT/4gtv.png" - if [[ ! -x $(command -v convert) ]] - then - Println "$info 安装 ImageMagick" - ImageMagickInstall - fi + ImageMagickInstall while true do @@ -70,7 +66,6 @@ Login4gtvAcc() read -p "(默认: 刷新验证码): " validatecode [ -z "$validatecode" ] && continue else - Println "$info 尝试修复 magick ..." ImageMagickInstall rm -f "${IMG_FILE:-notfound}" Println "$error 连接发生错误, 请重试\n" @@ -95,7 +90,7 @@ Login4gtvAcc() done jq_path='["4gtv","accounts",'"$_4gtv_accs_index"',"token"]' - JQ update "$SERVICES_FILE" "$token" + JQ update "$SERVICES_CONFIG" "$token" Println "$info 账号登录成功" Println "$info 验证账号..." for((i=0;i<3;i++)); @@ -117,7 +112,7 @@ Login4gtvAcc() fi done Println "$info 账号验证成功" - Println "$info 开启 7 天豪华套餐" + Println "$info 开启 30 天豪华套餐" IFS="^" read -r result msg < <(CurlFake -s -Lm 20 \ -H 'Origin: https://www.4gtv.tv' \ @@ -129,8 +124,8 @@ Login4gtvAcc() if [ "$result" = true ] then - Println "$info 7 天豪华套餐开启成功\n" + Println "$info 30 天豪华套餐开启成功\n" else - Println "$error 开启 7 天豪华套餐发生错误, 请重试\n\n$msg\n" + Println "$error 开启 30 天豪华套餐发生错误, 请重试\n\n$msg\n" fi } diff --git a/src/_4gtv/reg_acc b/src/_4gtv/reg_acc index 14227f7..b3461e2 100644 --- a/src/_4gtv/reg_acc +++ b/src/_4gtv/reg_acc @@ -10,11 +10,11 @@ Reg4gtvAcc() | $JQ_FILE -r '[.Success,.ErrMessage]|join(" ")' ) || true - if [ "$result" = true ] + if [ "$result" = true ] || [ "$msg" = "String was not recognized as a valid DateTime." ] then - if [ ! -s "$SERVICES_FILE" ] + if [ ! -s "$SERVICES_CONFIG" ] then - printf '{"%s":{"%s":[]}}' "4gtv" "accounts" > "$SERVICES_FILE" + printf '{"%s":{"%s":[]}}' "4gtv" "accounts" > "$SERVICES_CONFIG" fi new_acc=$( $JQ_FILE -n --arg email "$_4gtv_acc_email" --arg password "$_4gtv_acc_pass" \ @@ -24,7 +24,7 @@ Reg4gtvAcc() }' ) jq_path='["4gtv","accounts"]' - JQ add "$SERVICES_FILE" "[$new_acc]" + JQ add "$SERVICES_CONFIG" "[$new_acc]" Println "$info 账号注册成功\n" else Println "$error 账号注册失败, 请重试\n\n$msg\n" diff --git a/src/ali b/src/ali index 9654010..9cdee74 100644 --- a/src/ali +++ b/src/ali @@ -1,9 +1,7 @@ -Include src/iptv/get_service -Include src/alist/add_app -Include src/alist/view_app -Include src/alist/add_acc -Include src/alist/view_acc -Include src/alist/login_acc +Include src/service/get +Include src/service/control +Include src/alist/app +Include src/alist/acc Include src/alist/api Include src/alist/act @@ -17,19 +15,19 @@ case $alist_options_index in ;; 1) echo - alist_app_options=( '查看' '添加' '安装' '修改' '删除' ) + alist_app_options=( '查看' '添加' '修改' '删除' '本地安装/升级' ) inquirer list_input_index "选择操作" alist_app_options alist_app_options_index case $alist_app_options_index in - 0) AlistViewApp + 0) AlistAppView ;; - 1) AlistAddApp + 1) AlistAppAdd ;; - 2) AlistInstallApp + 2) AlistAppEdit ;; - 3) AlistEditApp + 3) AlistAppDel ;; - 4) AlistDelApp + 4) AlistAppInstall ;; esac ;; @@ -39,15 +37,15 @@ case $alist_options_index in inquirer list_input_index "选择操作" alist_acc_options alist_acc_options_index case $alist_acc_options_index in - 0) AlistViewAcc + 0) AlistAccView ;; - 1) AlistAddAcc + 1) AlistAccAdd ;; - 2) AlistLoginAcc + 2) AlistAccLogin ;; - 3) AlistEditAcc + 3) AlistAccEdit ;; - 4) AlistDelAcc + 4) AlistAccDel ;; esac ;; diff --git a/src/alist/acc b/src/alist/acc new file mode 100644 index 0000000..777603d --- /dev/null +++ b/src/alist/acc @@ -0,0 +1,192 @@ +AlistAccAdd() +{ + ServiceGet alist + + if [ "$alists_count" -eq 0 ] + then + Println "$error 请先添加 Alist\n" + exit 1 + fi + + alists_options=() + for((i=0;i $alist_file_name\n" + Alist.fs.rename + done else echo alist_files_txt="" diff --git a/src/alist/add_acc b/src/alist/add_acc deleted file mode 100644 index 8d2effc..0000000 --- a/src/alist/add_acc +++ /dev/null @@ -1,70 +0,0 @@ -AlistAddAcc() -{ - GetServiceAccs alist - - if [ "$alists_count" -eq 0 ] - then - Println "$error 请先添加 Alist\n" - exit 1 - fi - - alists_options=() - for((i=0;i/dev/null || true + fi + + printf -v date '%(%m-%d-%H:%M:%S)T' -1 + alist_backup="$ALIST_ROOT-$date" + mv "$ALIST_ROOT" "$alist_backup" + else + echo + ExitOnText "设置 Alist admin 密码" alist_pass + fi + + if [ "$dist" == "mac" ] + then + alist_pack_name="alist-darwin" + else + alist_pack_name="alist-linux-musl" + fi + + ArchCheck + + if [ "$arch" == "x86_64" ] + then + alist_pack_name="${alist_pack_name}-amd64.tar.gz" + elif [ "$arch" == "s390x" ] + then + alist_pack_name="${alist_pack_name}-s390x.tar.gz" + else + alist_pack_name="${alist_pack_name}-arm64.tar.gz" + fi + + if ! TMP_DIR=$(mktemp -q -d) + then + printf -v TMP_DIR '%(%m-%d-%H:%M:%S)T' -1 + mkdir -p "$TMP_DIR" + fi + + trap ' + rm -rf "${TMP_DIR:-notfound}" + ' EXIT + + cd "$TMP_DIR" + + if ! curl -O -L "$ALIST_LINK/releases/latest/download/$alist_pack_name" && ! curl -O -L "$ALIST_LINK_FALLBACK/releases/latest/download/$alist_pack_name" + then + Println "$error 无法下载 Alist, 请稍后再试\n" + return 1 + fi + + mkdir "$ALIST_ROOT" + tar zxf "$TMP_DIR/$alist_pack_name" -C "$ALIST_ROOT"/ + + if [ -n "${alist_backup:-}" ] && [ -d "${alist_backup}/data" ] + then + cp -r "$alist_backup"/data "$ALIST_ROOT"/ + else + mkdir -p "$ALIST_ROOT"/data/log + alist_config=$( + $JQ_FILE -n --arg db_file "${ALIST_ROOT}/data/data.db" --arg bleve_dir "${ALIST_ROOT}/data/bleve" \ + --arg log "${ALIST_ROOT}/data/log/log.log" \ + '{ + "force": false, + "site_url": "", + "cdn": "", + "jwt_secret": "", + "token_expires_in": 48, + "database": { + "type": "sqlite3", + "host": "", + "port": 0, + "user": "", + "password": "", + "name": "", + "db_file": $db_file, + "table_prefix": "x_", + "ssl_mode": "", + "dsn": "" + }, + "meilisearch": { + "host": "http://localhost:7700", + "api_key": "", + "index_prefix": "" + }, + "scheme": { + "address": "127.0.0.1", + "http_port": 5244, + "https_port": -1, + "force_https": false, + "cert_file": "", + "key_file": "", + "unix_file": "", + "unix_file_perm": "" + }, + "temp_dir": "/tmp/alist", + "bleve_dir": $bleve_dir, + "dist_dir": "", + "log": { + "enable": true, + "name": $log, + "max_size": 10, + "max_backups": 5, + "max_age": 28, + "compress": false + }, + "delayed_start": 0, + "max_connections": 0, + "tls_insecure_skip_verify": true, + "tasks": { + "download": { + "workers": 5, + "max_retry": 1 + }, + "transfer": { + "workers": 5, + "max_retry": 2 + }, + "upload": { + "workers": 5, + "max_retry": 0 + }, + "copy": { + "workers": 5, + "max_retry": 2 + } + }, + "cors": { + "allow_origins": [ + "*" + ], + "allow_methods": [ + "*" + ], + "allow_headers": [ + "*" + ] + }, + "s3": { + "enable": false, + "port": 5246, + "ssl": false + } + }' + ) + + echo "$alist_config" > "$ALIST_ROOT"/data/config.json + cd "$ALIST_ROOT" + ./alist admin set "$alist_pass" + fi + + service_name="alist" + + service_commands=( "$ALIST_ROOT"/alist server --data "$ALIST_ROOT"/data ) + + if ! err_msg=$(ServiceControl start "$service_name" service_commands) + then + Println "$error $service_name 启动失败, $err_msg\n" + return 1 + fi + + rm -rf "${TMP_DIR:-notfound}" + trap - EXIT + + Println "$info Alist 安装成功\n" +} diff --git a/src/alist/login_acc b/src/alist/login_acc deleted file mode 100644 index 32ada05..0000000 --- a/src/alist/login_acc +++ /dev/null @@ -1,68 +0,0 @@ -AlistLoginAcc() -{ - DepInstall curl - - GetServiceAccs alist - - if [ "$alists_count" -eq 0 ] - then - Println "$error 请先添加 Alist\n" - exit 1 - fi - - alists_options=() - for((i=0;i /etc/NetworkManager/system-connections/armbian.nmconnection then if [ -f /etc/NetworkManager/dispatcher.d/promisc.sh ] then - printf '%s' '#!/usr/bin/env bash +cat > /etc/NetworkManager/dispatcher.d/90-promisc.sh < /etc/NetworkManager/dispatcher.d/90-promisc.sh + ip link set \$interface promisc on + echo "\$interface received \$event" | systemd-cat -p info -t dispatch_script +fi +EOF rm -f /etc/NetworkManager/dispatcher.d/promisc.sh chmod +x /etc/NetworkManager/dispatcher.d/90-promisc.sh @@ -588,16 +590,18 @@ method=ignore" > /etc/NetworkManager/system-connections/hMACvLAN.nmconnection if [ ! -s /etc/NetworkManager/dispatcher.d/90-promisc.sh ] then - printf '%s' '#!/usr/bin/env bash +cat > /etc/NetworkManager/dispatcher.d/90-promisc.sh < /etc/NetworkManager/dispatcher.d/90-promisc.sh + ip link set \$interface promisc on + echo "\$interface received \$event" | systemd-cat -p info -t dispatch_script +fi +EOF rm -f /etc/NetworkManager/dispatcher.d/promisc.sh chmod +x /etc/NetworkManager/dispatcher.d/90-promisc.sh diff --git a/src/calibre/install b/src/calibre/install new file mode 100644 index 0000000..bc472ac --- /dev/null +++ b/src/calibre/install @@ -0,0 +1,59 @@ +CalibreInstall() +{ + if [ "$dist" == "mac" ] + then + brew install --cask calibre + else + DepInstall wget + DepInstall xdg-utils + if [ "$dist" == "rpm" ] + then + DepInstall xz + DepInstall libglvnd-opengl + DepInstall libxcb-cursor-devel + DepInstall nss + else + DepInstall xz-utils + DepInstall libopengl0 + DepInstall libxcb-cursor0 + DepInstall libnss3 + fi + ImageMagickInstall + DepInstall libegl1 + PythonInstall + pip3 install pyqt6 + mkdir -p "$CALIBRE_ROOT"/bin + sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin install_dir="$CALIBRE_ROOT"/bin + fi + + Println "$info calibre 安装/更新成功\n" +} + +CalibrePluginInstall() +{ + if { [ "$dist" == "mac" ] && [ ! -d /Applications/calibre.app ]; } || { [ "$dist" != "mac" ] && [ ! -d "$CALIBRE_ROOT"/bin ]; } + then + CalibreInstall + fi + + if [ "$dist" == "mac" ] + then + CALIBRE_BIN_ROOT="/Applications/calibre.app/Contents/MacOS" + else + CALIBRE_BIN_ROOT="$CALIBRE_ROOT"/bin/calibre + fi + + local plugin_name="$1" plugin_grep=$("$CALIBRE_BIN_ROOT"/calibre-customize -l) + if ! grep -q "$plugin_name" <<< "$plugin_grep" + then + DepInstall curl + mkdir -p "$CALIBRE_ROOT"/plugins + if ! curl -L -o "${CALIBRE_ROOT}/plugins/${plugin_name}.zip" "$FFMPEG_MIRROR_LINK/calibre/plugins/${plugin_name}.zip" + then + Println "$error $plugin_name 插件不存在\n" + return 1 + fi + "$CALIBRE_BIN_ROOT"/calibre-customize -a "${CALIBRE_ROOT}/plugins/${plugin_name}.zip" + Println "$info $plugin_name 插件安装成功\n" + fi +} diff --git a/src/calibre/kcc b/src/calibre/kcc new file mode 100644 index 0000000..dfcd1a0 --- /dev/null +++ b/src/calibre/kcc @@ -0,0 +1,455 @@ +KccInstall() +{ + if [[ -x "$KCC_FILE" ]] + then + cd "$CALIBRE_ROOT/kcc" + git pull + Println "$info KCC 更新成功\n" + return 0 + fi + DepInstall git + PythonInstall + git clone https://github.com/ciromattia/kcc.git "$KCC_ROOT" + cd "$KCC_ROOT" + python3 -m venv venv + source venv/bin/activate + pip install -r requirements.txt + Println "$info KCC 安装成功\n" +} + +KccView() +{ + ServiceGet kcc + + if [ -z "${kcc_output:-}" ] + then + Println "$error 请先设置 kcc\n" + return 1 + fi + + local kcc_list="输出格式: $kcc_format\n" + + if [ "$kcc_process" = true ] + then + kcc_list="${kcc_list}处理图片: 是\n" + else + kcc_list="${kcc_list}处理图片: 否\n" + fi + + if [ -n "${kcc_sources:-}" ] + then + kcc_source=$(JoinByString ', ' "${kcc_sources[@]}") + fi + + kcc_list="${kcc_list}额外参数: ${kcc_args:-无}\n输出目录: $kcc_output\n源图片: ${kcc_source:-无}\n" + + Println "$kcc_list" +} + +KccBrowse() +{ + KccView + + kcc_view_options=( '输出目录' '源图片' ) + + echo + inquirer list_input_index "请选择" kcc_view_options kcc_view_options_index + + if [ "$kcc_view_options_index" -eq 0 ] + then + ServiceBrowse "$kcc_output" + elif [ "$kcc_view_options_index" -eq 1 ] + then + if [ -z "${kcc_sources:-}" ] + then + Println "$error 请先添加源图片目录\n" + return 1 + fi + echo + inquirer list_input_index "请选择源图片目录" kcc_sources kcc_sources_index + ServiceBrowse "${kcc_sources[kcc_sources_index]}" + fi +} + +KccConfig() +{ + ServiceGet kcc + + kcc_format_options=( Auto MOBI EPUB CBZ KFX MOBI+EPUB ) + + echo + inquirer list_input "选择输出格式" kcc_format_options kcc_format + + echo + inquirer list_input_index "是否处理图片" ny_options ny_index + + if [ "$ny_index" -eq 0 ] + then + kcc_process=false + kcc_args="" + else + kcc_process=true + echo + inquirer text_input "输入额外参数" kcc_args "$i18n_not_set" + if [ "$kcc_args" == "$i18n_not_set" ] + then + kcc_args="" + fi + fi + + echo + ExitOnText "设置输出目录" kcc_output + RemoveQuotes kcc_output + + kcc_sources=() + + while true + do + echo + inquirer text_input "输入源图片目录" kcc_source + RemoveQuotes kcc_source + if [ -z "$kcc_source" ] + then + Println "$error 源图片目录不能为空" + else + kcc_sources+=("$kcc_source") + echo + inquirer list_input_index "继续添加源图片目录" ny_options ny_index + if [ "$ny_index" -eq 0 ] + then + break + fi + fi + done + + kcc_payload=$( + $JQ_FILE -c -n --arg format "$kcc_format" --arg process "$kcc_process" \ + --arg args "$kcc_args" --arg output "$kcc_output" \ + --argjson source "$(ToJsonArray kcc_sources)" \ + '{ + format: $format, + process: $process | test("true"), + args: $args, + output: $output, + source: $source + }' + ) + + json=true + jq_path='["kcc"]' + JQ update "$SERVICES_CONFIG" "$kcc_payload" + + Println "$info kcc 设置成功\n" +} + +KccConfigEdit() +{ + KccView + + kcc_config_edit_options=( '输出格式' '是否处理图片' '额外参数' '输出目录' '添加源图片目录' '修改源图片目录' '删除源图片目录' ) + kcc_format_options=( Auto MOBI EPUB CBZ KFX MOBI+EPUB ) + + echo + inquirer checkbox_input_indices "请选择修改内容" kcc_config_edit_options kcc_config_edit_options_indices + + for kcc_config_edit_options_index in "${kcc_config_edit_options_indices[@]}" + do + case $kcc_config_edit_options_index in + 0) + echo + inquirer list_input "选择输出格式" kcc_format_options new_kcc_format + if [ "$new_kcc_format" != "$kcc_format" ] + then + jq_path='["kcc","format"]' + JQ update "$SERVICES_CONFIG" "$new_kcc_format" + Println "$info 输出格式修改成功\n" + fi + ;; + 1) + echo + inquirer list_input_index "是否处理图片" ny_options ny_index + if [ "$ny_index" -eq 0 ] + then + new_kcc_process=false + else + new_kcc_process=true + fi + + if [ "$new_kcc_process" != "$kcc_process" ] + then + bool=true + jq_path='["kcc","process"]' + JQ update "$SERVICES_CONFIG" "$new_kcc_process" + Println "$info 是否处理图片修改成功\n" + fi + ;; + 2) + echo + inquirer text_input "输入额外参数" new_kcc_args "$i18n_not_set" + if [ "$new_kcc_args" == "$i18n_not_set" ] + then + new_kcc_args="" + fi + if [ "$new_kcc_args" != "$kcc_args" ] + then + jq_path='["kcc","args"]' + JQ update "$SERVICES_CONFIG" "$new_kcc_args" + Println "$info 额外参数修改成功\n" + fi + ;; + 3) + echo + inquirer text_input "设置输出目录" new_kcc_output "$kcc_output" + RemoveQuotes new_kcc_output + if [ "$new_kcc_output" != "$kcc_output" ] + then + jq_path='["kcc","output"]' + JQ update "$SERVICES_CONFIG" "$new_kcc_output" + Println "$info 输出目录修改成功\n" + fi + ;; + 4) + while true + do + echo + inquirer text_input "输入源图片目录" new_kcc_source "$i18n_not_set" + if [ "$new_kcc_source" == "$i18n_not_set" ] + then + break + fi + RemoveQuotes new_kcc_source + if [ -z "$new_kcc_source" ] + then + Println "$error 源图片目录不能为空" + elif EleInArray "$new_kcc_source" kcc_sources + then + Println "$error 源图片目录已存在" + else + kcc_sources+=("$new_kcc_source") + echo + inquirer list_input_index "继续添加源图片目录" ny_options ny_index + if [ "$ny_index" -eq 0 ] + then + break + fi + fi + done + json=true + jq_path='["kcc","source"]' + JQ update "$SERVICES_CONFIG" "$(ToJsonArray kcc_sources)" + Println "$info 源图片目录添加成功\n" + ;; + 5) + if [ -z "${kcc_sources:-}" ] + then + Println "$error 请先添加源图片目录\n" + return 1 + fi + + echo + inquirer checkbox_input_indices "请选择源图片目录" kcc_sources kcc_sources_indices + + kcc_source_update=false + + for kcc_sources_index in "${kcc_sources_indices[@]}" + do + while true + do + echo + inquirer text_input "修改源图片目录 ${kcc_sources[kcc_sources_index]}" new_kcc_source "$i18n_not_set" + if [ "$new_kcc_source" == "$i18n_not_set" ] + then + continue 2 + fi + RemoveQuotes new_kcc_source + if [ -z "$new_kcc_source" ] + then + Println "$error 源图片目录不能为空" + elif EleInArray "$new_kcc_source" kcc_sources + then + Println "$error 源图片目录已存在" + else + kcc_sources[$kcc_sources_index]="$new_kcc_source" + kcc_source_update=true + break + fi + done + done + + if [ "$kcc_source_update" = true ] + then + json=true + jq_path='["kcc","source"]' + JQ update "$SERVICES_CONFIG" "$(ToJsonArray kcc_sources)" + Println "$info 源图片目录修改成功\n" + fi + ;; + 6) + if [ -z "${kcc_sources:-}" ] + then + Println "$error 请先添加源图片目录\n" + return 1 + fi + + echo + inquirer checkbox_input_indices "请选择源图片目录" kcc_sources kcc_sources_indices + + for kcc_sources_index in "${kcc_sources_indices[@]}" + do + unset kcc_sources[$kcc_sources_index] + done + + json=true + jq_path='["kcc","source"]' + + if [ "${#kcc_sources[@]}" -eq 0 ] + then + JQ update "$SERVICES_CONFIG" "[]" + else + kcc_sources=("${kcc_sources[@]}") + JQ update "$SERVICES_CONFIG" "$(ToJsonArray kcc_sources)" + fi + + Println "$info 源图片目录删除成功\n" + ;; + esac + done + + return 0 +} + +KccConvert() +{ + local source="$1" + shift + local files_indices=( "$@" ) files_index kcc_commands=() kcc_output_name + shopt -s nullglob + local files=("$source"/*) + shopt -u nullglob + + local kcc_convert_formats=( Auto MOBI EPUB CBZ KFX MOBI+EPUB ) format + + if [ "${kcc_format:-Auto}" != "Auto" ] + then + kcc_convert_formats=( "$kcc_format" ) + for format in Auto MOBI EPUB CBZ KFX MOBI+EPUB + do + if [ "$format" != "$kcc_format" ] + then + kcc_convert_formats+=( "$format" ) + fi + done + fi + + if [ "${kcc_format:-Auto}" != "KFX Output" ] + then + kcc_convert_formats+=( 'KFX Output' ) + fi + + kcc_convert_outputs=( "$kcc_output" '当前目录' '输入新目录' ) + + echo + inquirer list_input_index "选择输出目录" kcc_convert_outputs kcc_convert_outputs_index + + case $kcc_convert_outputs_index in + 1) kcc_output="$source" + ;; + 2) + echo + inquirer text_input "输入转换输出的目录" kcc_output "$kcc_output" + RemoveQuotes kcc_output + ;; + esac + + echo + inquirer list_input "选择输出格式" kcc_convert_formats kcc_format + + if [ "$kcc_format" == "KFX Output" ] + then + for files_index in "${files_indices[@]}" + do + if [ -d "${files[files_index]}" ] || [ "${files[files_index]##*.}" != "kpf" ] + then + Println "$error 请只选择kpf文件\n" + return 1 + fi + done + + CalibrePluginInstall 'KFX Output' + + for files_index in "${files_indices[@]}" + do + kcc_output_name="${files[files_index]##*/}" + kcc_output_name="${kcc_output_name%.*}.kfx" + "$CALIBRE_BIN_ROOT"/calibre-debug -r "KFX Output" -- "${files[files_index]}" "${kcc_output}/${kcc_output_name}" + Println "$info ${files[files_index]##*/} 转换成功\n" + done + + return 0 + fi + + for files_index in "${files_indices[@]}" + do + if [ ! -d "${files[files_index]}" ] + then + Println "$error 请只选择图片目录\n" + return 1 + fi + done + + if [ "${kcc_process:-false}" = false ] + then + kcc_commands+=( -n ) + elif [ -n "$kcc_args" ] + then + kcc_commands+=($kcc_args) + fi + + source "${KCC_ROOT}/venv/bin/activate" + + for files_index in "${files_indices[@]}" + do + python3 "$KCC_FILE" ${kcc_commands+"${kcc_commands[@]}"} -f "$kcc_format" -o "$kcc_output"/ "${files[files_index]}" + Println "$info ${files[files_index]##*/} 转换成功\n" + done + + return 0 +} + +KccMenu() +{ + kcc_options=( '浏览' '转换' '设置' '修改设置' '更新/安装' ) + echo + inquirer list_input_index "请选择" kcc_options kcc_options_index + + case $kcc_options_index in + 0) KccBrowse + ;; + 1) + KccView + + if [ -z "${kcc_sources:-}" ] + then + Println "$error 请先添加源图片目录\n" + return 1 + fi + + if [[ ! -x "$KCC_FILE" ]] + then + Println "$error 请先安装 kcc\n" + return 1 + fi + + echo + inquirer list_input_index "选择源图片目录" kcc_sources kcc_sources_index + + ServiceBrowse "${kcc_sources[$kcc_sources_index]}" "转换" KccConvert + ;; + 2) KccConfig + ;; + 3) KccConfigEdit + ;; + 4) KccInstall + ;; + esac +} diff --git a/src/calibre/web b/src/calibre/web new file mode 100644 index 0000000..ce06b03 --- /dev/null +++ b/src/calibre/web @@ -0,0 +1,103 @@ +CalibreWebInstall() +{ + if [ -d "$CALIBRE_ROOT/web" ] + then + cd "$CALIBRE_ROOT/web" + git pull + Println "$info Calibre Web 更新成功\n" + return + fi + + DepInstall git + PythonInstall + git clone https://github.com/janeczku/calibre-web.git "$CALIBRE_ROOT/web" + cd "$CALIBRE_ROOT/web" + if [ "$dist" == "ubu" ] || [ "$dist" == "deb" ] + then + python3 -m pip install virtualenv + virtualenv venv + else + python3 -m venv venv + fi + ./venv/bin/python3 -m pip install -r requirements.txt + Println "$info Calibre Web 安装成功\n" +} + +CalibreWebStart() +{ + service_name="calibre-web" + + if ServiceControl is-active "$service_name" + then + Println "$error $service_name 已运行\n" + return 1 + fi + + service_commands=( "$CALIBRE_ROOT"/web/venv/bin/python3 "$CALIBRE_ROOT"/web/cps.py ) + + if ! err_msg=$(ServiceControl start "$service_name" service_commands) + then + Println "$error $service_name 启动失败, $err_msg\n" + return 1 + fi + + Println "$info $service_name 启动成功\n" +} + +CalibreWebStop() +{ + service_name="calibre-web" + + if ! ServiceControl is-active "$service_name" + then + Println "$error $service_name 未运行\n" + return 1 + fi + + if ! err_msg=$(ServiceControl stop "$service_name") + then + Println "$error $service_name 关闭失败, $err_msg\n" + return 1 + fi + + Println "$info $service_name 关闭成功\n" +} + +CalibreWebRestart() +{ + service_name="calibre-web" + + if ServiceControl is-active "$service_name" && ! err_msg=$(ServiceControl stop "$service_name") + then + Println "$error $service_name 关闭失败, $err_msg\n" + return 1 + fi + + service_commands=( "$CALIBRE_ROOT"/web/venv/bin/python3 "$CALIBRE_ROOT"/web/cps.py ) + + if ! err_msg=$(ServiceControl start "$service_name" service_commands) + then + Println "$error $service_name 重启失败, $err_msg\n" + return 1 + fi + + Println "$info $service_name 重启成功\n" +} + +CalibreWebView() +{ + service_name="calibre-web" + + if ! ServiceControl is-active "$service_name" + then + Println "$error $service_name 未运行\n" + return 1 + fi + + Println "$info 访问 Calibre Web: http://localhost:8083 , 用户名 admin 初始密码 admin123\n" + + if [ "$dist" == "mac" ] + then + open "http://localhost:8083" + fi +} diff --git a/src/cw b/src/cw new file mode 100644 index 0000000..048d7bd --- /dev/null +++ b/src/cw @@ -0,0 +1,29 @@ +Include src/calibre/web "$@" +Include src/calibre/kcc "$@" +Include src/calibre/install "$@" +Include src/service/control "$@" +Include src/service/get "$@" +Include src/service/browse "$@" +Include utils/python "$@" +Include utils/imagemagick "$@" + +calibre_options=( 'kcc' '安装/更新 calibre' '开启 Calibre Web' '关闭 Calibre Web' '重启 Calibre Web' '查看 Calibre Web' '安装/更新 Calibre Web' ) +echo +inquirer list_input_index "请选择" calibre_options calibre_options_index + +case $calibre_options_index in + 0) KccMenu + ;; + 1) CalibreInstall + ;; + 2) CalibreWebStart + ;; + 3) CalibreWebStop + ;; + 4) CalibreWebRestart + ;; + 5) CalibreWebView + ;; + 6) CalibreWebInstall + ;; +esac diff --git a/src/ibm_cf/deploy_v2ray b/src/ibm_cf/deploy_v2ray index 9478450..1fbe870 100644 --- a/src/ibm_cf/deploy_v2ray +++ b/src/ibm_cf/deploy_v2ray @@ -92,12 +92,13 @@ applications: GOPACKAGENAME: goapp " > "${ibm_cf_app_name}_manifest.yml" - printf '%s' 'package main +cat > main.go < "main.go" +EOF ibmcloud cf push -f "${ibm_cf_app_name}_manifest.yml" cd .. rm -rf "$IBM_APPS_ROOT/ibm_$v2ray_rand_name" diff --git a/src/ibm_cf/exec_cron b/src/ibm_cf/exec_cron index 7953aca..309ab9d 100644 --- a/src/ibm_cf/exec_cron +++ b/src/ibm_cf/exec_cron @@ -93,12 +93,13 @@ applications: GOPACKAGENAME: goapp " > "${apps_name[i]}_manifest.yml" - printf '%s' 'package main +cat > main.go < "main.go" +EOF ibmcloud cf push -f "${apps_name[i]}_manifest.yml" cd .. rm -rf "$IBM_APPS_ROOT/ibm_$v2ray_rand_name" diff --git a/src/ibm_cf/update_v2ray_config b/src/ibm_cf/update_v2ray_config index 4724425..95df55b 100644 --- a/src/ibm_cf/update_v2ray_config +++ b/src/ibm_cf/update_v2ray_config @@ -6,7 +6,8 @@ IbmUpdateV2rayConfig() exit 1 elif [ ! -s "$V2_CONFIG" ] then - printf '%s' '{ +cat > "$V2_CONFIG" < "$V2_CONFIG" +} +EOF fi } diff --git a/src/iptv/cmd_add b/src/iptv/cmd_add index 83de932..e737c06 100644 --- a/src/iptv/cmd_add +++ b/src/iptv/cmd_add @@ -1,4 +1,4 @@ -while getopts "i:l:P:o:p:S:t:s:c:v:a:f:q:b:r:k:K:m:n:z:H:T:L:CRe" flag +while getopts "i:l:P:o:p:S:t:s:c:v:a:f:q:b:r:k:K:m:n:z:H:T:L:CReh" flag do case "$flag" in i) stream_link="$OPTARG";; @@ -27,7 +27,7 @@ do H) flv_h265=true;; T) flv_push_link="$OPTARG";; L) flv_pull_link="$OPTARG";; - *) Usage; + h|*) Usage; esac done diff --git a/src/iptv/cmd_backup b/src/iptv/cmd_backup index 0f0a6aa..0e9172c 100644 --- a/src/iptv/cmd_backup +++ b/src/iptv/cmd_backup @@ -1,3 +1,213 @@ -echo +# --exclude=exclude_before --include=src/ --include=src/xxx/*** --exclude=src/*** --exclude=exclude_after + +IPTV_ROOT="${IPTV_ROOT%/}" +FFMPEG_MIRROR_ROOT="${FFMPEG_MIRROR_ROOT%/}" +LIVE_ROOT="${LIVE_ROOT%/}" +NODE_ROOT="${NODE_ROOT%/}" + +iptv_source="$IPTV_ROOT" + +iptv_excludes_before=( + /c/ + /ffmpeg-git-'*' + /vip/ + node_modules/ +) + +ffmpeg_excludes_before=( + /Amlogic_s905-kernel-master.zip + /builds/ + /calibre/ + /dnscrypt/ + /ffmpeg_c + /fontforge-20190413.tar.gz + /imgcat.zip + /jq-'*' + /releases/ + /v2ray/ + /xray/ + '*'.ipk + '*'.err + '*'.log + '*'.pid +) + +if [[ "$FFMPEG_MIRROR_ROOT" =~ "$iptv_source"(.*) ]] +then + relative_path="${BASH_REMATCH[1]:-}" + relative_path="${relative_path#/}" + if [ -n "$relative_path" ] + then + for i in "${!ffmpeg_excludes_before[@]}" + do + if [[ "${ffmpeg_excludes_before[i]}" == /* ]] + then + ffmpeg_excludes_before[i]="/${relative_path}${ffmpeg_excludes_before[i]}" + else + ffmpeg_excludes_before[i]="/$relative_path/${ffmpeg_excludes_before[i]}" + fi + done + fi + iptv_excludes_before+=("${ffmpeg_excludes_before[@]}") +else + ffmpeg_source="$FFMPEG_MIRROR_ROOT" +fi + +if [[ "$LIVE_ROOT" =~ "$IPTV_ROOT"(.+) ]] +then + iptv_excludes_before+=("${BASH_REMATCH[1]}") +fi + +node_excludes_before=( + node_modules/ +) + +if ! [[ "$NODE_ROOT" =~ "$IPTV_ROOT"(.*) ]] +then + node_source="$NODE_ROOT" +fi + +nginx_source=/usr/local/nginx + +nginx_excludes_before=( + /logs/'*'.gz + node_modules/ +) + +nginx_includes=( + /conf/'***' + /html/'***' + /logs/'***' +) + +nginx_excludes_after=( + /'***' +) + +openresty_source=/usr/local/openresty + +openresty_excludes_before=( + /nginx/logs/'*'.gz + node_modules/ +) + +openresty_includes=( + /nginx/ + /nginx/conf/'***' + /nginx/html/'***' + /nginx/logs/'***' + /nginx/lua/'***' +) + +openresty_excludes_after=( + /'***' +) + +v2ray_source="${V2_CONFIG%/*}" + +xray_source="${X_CONFIG%/*}" + +if [ "$dist" == "mac" ] +then + systemd_source="$HOME"/Library/LaunchAgents +else + systemd_source=/etc/systemd/system +fi + +systemd_includes=( + /alist.service + /aria2.service + /dnscrypt-proxy.service + /mmproxy-'*'.service + /nginx.service + /openresty.service + /v2ray.service + /xray.service + /aios.'*'.service + /com.aios.'*'.plist +) + +systemd_excludes_after=( + /'***' +) + +services_source="$SERVICES_ROOT" + +services_excludes_before=( + venv/ + node_modules/ + .git/ + /calibre/bin/ + /calibre/kcc/ +) + +home_source="$HOME" + +home_includes=( + /.bash_history +) + +home_excludes_after=( + /'***' +) + +DepInstall rsync + +mkdir -p "$BACKUP_ROOT" + +for backup in iptv nginx openresty v2ray xray ffmpeg node systemd services home +do + rsync_commands=() + source="${backup}_source" + + if [[ -z "${!source:-}" ]] + then + continue + fi + + source="${!source}" + + if [ ! -d "$source" ] + then + continue + fi + + excludes_before=("${backup}_excludes_before"[@]) + + if [[ -n "${!excludes_before:-}" ]] + then + excludes_before=("${!excludes_before}") + for exclude in "${excludes_before[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + includes=("${backup}_includes"[@]) + + if [[ -n "${!includes:-}" ]] + then + includes_arr=("${!includes}") + for include in "${includes_arr[@]}" + do + rsync_commands+=( --include="$include" ) + done + fi + + excludes_after=("${backup}_excludes_after"[@]) + + if [[ -n "${!excludes_after:-}" ]] + then + excludes_after=("${!excludes_after}") + for exclude in "${excludes_after[@]}" + do + rsync_commands+=( --exclude="$exclude" ) + done + fi + + rsync -avP --safe-links --delete --delete-excluded ${rsync_commands[@]+"${rsync_commands[@]}"} "$source/" "$BACKUP_ROOT/$backup/" +done + +Println "$info 已创建备份 $BACKUP_ROOT\n" exit 0 diff --git a/src/iptv/get_service b/src/iptv/get_service deleted file mode 100644 index 7991ff5..0000000 --- a/src/iptv/get_service +++ /dev/null @@ -1,90 +0,0 @@ -GetServiceAccs() -{ - local service_id=$1 - - if [ ! -s "$SERVICES_FILE" ] - then - printf '{"%s":{"%s":[]}}' "$service_id" "accounts" > "$SERVICES_FILE" - fi - - SetDelimiters - - if [ "$service_id" == "4gtv" ] - then - IFS=$'\003\t' read -r d_4gtv_proxy _4gtv_acc_email _4gtv_acc_pass _4gtv_acc_token < <(JQs flat "$SERVICES_FILE" '' ' - [(."'"$service_id"'".proxy // "") + "\u0003"] + ((."'"$service_id"'".accounts | if (.|type == "string") then {} else . end) as $accounts | - reduce ({email,password,token}|keys_unsorted[]) as $key ([]; - $accounts[$key] as $val | if $val then - . + [$val + "\u0002\u0003"] - else - . + ["\u0003"] - end - ))|@tsv' "${delimiters[@]}") - - IFS="${delimiters[1]}" read -r -a _4gtv_accs_email <<< "$_4gtv_acc_email" - IFS="${delimiters[1]}" read -r -a _4gtv_accs_pass <<< "$_4gtv_acc_pass" - IFS="${delimiters[1]}" read -r -a _4gtv_accs_token <<< "$_4gtv_acc_token" - - _4gtv_accs_count=${#_4gtv_accs_email[@]} - elif [ "$service_id" == "alist" ] - then - IFS=$'\004\t' read -r alist_name alist_url alist_acc_username \ - alist_acc_password alist_acc_token < <(JQs flat "$SERVICES_FILE" '' ' - (."'"$service_id"'" | if (.|type == "string") then {} else . end) as $alist | - ($alist.accs // {} | if (.|type) == "string" then {} else . end) as $accs | - reduce ({name,url}|keys_unsorted[]) as $key ([]; - $alist[$key] as $val | if $val then - . + [$val + "\u0002\u0004"] - else - . + ["\u0004"] - end - ) + reduce ({username,password,token}|keys_unsorted[]) as $key ([]; - $accs[$key] as $val | if $val then - . + [$val + "\u0003\u0004"] - else - . + ["\u0004"] - end - )|@tsv' "${delimiters[@]}") - - IFS="${delimiters[1]}" read -r -a alists_name <<< "$alist_name" - IFS="${delimiters[1]}" read -r -a alists_url <<< "$alist_url" - IFS="${delimiters[2]}" read -r -a alists_acc_username <<< "$alist_acc_username" - IFS="${delimiters[2]}" read -r -a alists_acc_password <<< "$alist_acc_password" - IFS="${delimiters[2]}" read -r -a alists_acc_token <<< "$alist_acc_token" - - alists_count=${#alists_name[@]} - else - IFS=$'\003\t' read -r m_user_name m_phone_number m_password m_access_token m_device_no m_device_id m_refresh < <(JQs flat "$SERVICES_FILE" '' ' - (."'"$service_id"'".accounts | if (.|type == "string") then {} else . end) as $accounts | - reduce ({user_name,phone_number,password,access_token,device_no,device_id,refresh}|keys_unsorted[]) as $key ([]; - $accounts[$key] as $val | if $val then - . + [$val + "\u0002\u0003"] - else - . + ["\u0003"] - end - )|@tsv' "${delimiters[@]}") - - if [ -z "$m_user_name" ] - then - ts_accs_count=0 - return 0 - fi - - IFS="${delimiters[1]}" read -r -a ts_accs_user_name <<< "$m_user_name" - - if [ -z "$m_phone_number" ] - then - ts_accs_phone_number=("${ts_accs_user_name[@]//*/}") - else - IFS="${delimiters[1]}" read -r -a ts_accs_phone_number <<< "$m_phone_number" - fi - - IFS="${delimiters[1]}" read -r -a ts_accs_password <<< "$m_password" - IFS="${delimiters[1]}" read -r -a ts_accs_access_token <<< "$m_access_token" - IFS="${delimiters[1]}" read -r -a ts_accs_device_no <<< "$m_device_no" - IFS="${delimiters[1]}" read -r -a ts_accs_device_id <<< "$m_device_id" - IFS="${delimiters[1]}" read -r -a ts_accs_refresh <<< "$m_refresh" - - ts_accs_count=${#ts_accs_user_name[@]} - fi -} diff --git a/src/iptv/input_channels b/src/iptv/input_channels index 5493918..3472d90 100644 --- a/src/iptv/input_channels +++ b/src/iptv/input_channels @@ -79,7 +79,7 @@ InputChannelsIndex() continue 2 elif [[ $chnl_index_start -gt 0 ]] && [[ $chnl_index_end -le $chnls_count ]] && [[ $chnl_index_end -gt $chnl_index_start ]] then - ((chnl_index_start--)) + chnl_index_start=$((chnl_index_start-1)) for((i=chnl_index_start;i "$ebooks_config" + mkdir -p "$LIANHUANHUA_ROOT/" + printf '{"%s":{"%s":[]}}' "books" "zhlhh" > "$LIANHUANHUA_CONFIG" fi SetDelimiters - jq_input=$($JQ_FILE -c 'del(.books.hdlz)' "$ebooks_config") + jq_input=$($JQ_FILE -c 'del(.books.hdlz)' "$LIANHUANHUA_CONFIG") IFS=$'\003\t' read -r default_save_dir m_adapter m_addtime m_bookname m_category_id m_cover m_drawing m_m \ m_muludir m_original m_p m_publish m_yd m_downloaded m_fav < <(JQs flat "$jq_input" '' \ @@ -216,6 +219,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p result_yd=("${books_yd[@]}") result_p=("${books_p[@]}") iframe_paths=($(CurlFake -s -L -b "$COOKIE_FILE" -H "Referer: http://www.zhlhh.com/" "http://www.zhlhh.com/web/js/main.js" | grep -oP 'url = "\K[^"]+')) + books_indices=("${!books_m[@]}") else if EleInArray $((${#search_means[@]}-1)) search_keys_indices then @@ -229,7 +233,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p do if [ "$books_total" -gt 0 ] then - ((search_keys_index--)) + search_keys_index=$((search_keys_index-1)) fi case $search_keys_index in 0) @@ -366,14 +370,14 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p [ -n "${books:-}" ] && books="${books}," books="${books}${new_book}" books_indices+=("$books_total") - ((books_total++)) + books_total=$((books_total+1)) fi done if [ -n "${books:-}" ] then jq_path='["books","zhlhh"]' - JQ add "$ebooks_config" "[$books]" + JQ add "$LIANHUANHUA_CONFIG" "[$books]" fi fi @@ -390,6 +394,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p then echo inquirer text_input "输入存储文件夹目录" save_dir "${default_save_dir}" + RemoveQuotes save_dir if [ -z "$save_dir" ] then Println "已取消...\n" @@ -399,7 +404,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p if [ "$save_dir" != "$default_save_dir" ] then jq_path='["default","save_dir"]' - JQ update "$ebooks_config" "$save_dir" + JQ update "$LIANHUANHUA_CONFIG" "$save_dir" fi FFmpegInstall @@ -413,7 +418,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p then bool=true jq_path='["books","zhlhh",'"$books_index"',"downloaded"]' - JQ update "$ebooks_config" true + JQ update "$LIANHUANHUA_CONFIG" true fi done @@ -427,7 +432,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p then bool=true jq_path='["books","zhlhh",'"$books_index"',"fav"]' - JQ update "$ebooks_config" true + JQ update "$LIANHUANHUA_CONFIG" true fi done Println "$info 已添加到收藏\n" @@ -439,7 +444,7 @@ reduce ({adapter,addtime,bookname,category_id,cover,drawing,m,muludir,original,p then bool=true jq_path='["books","zhlhh",'"$books_index"',"fav"]' - JQ update "$ebooks_config" false + JQ update "$LIANHUANHUA_CONFIG" false fi done Println "$info 已取消收藏\n" @@ -461,7 +466,7 @@ HdlzZhihuDownload() book_path="${book_path%-*}" fi book_path="${book_path}-$i" - ((i++)) + i=$((i+1)) done if ! book_images=($(LhhDownload -s -L -b "$COOKIE_FILE" "https://zhuanlan.zhihu.com/p/${id}" | grep -oP 'data-original-token="\K[^"]+' | uniq)) @@ -503,7 +508,7 @@ HdlzZhihuDownload() book_images_name="${book_images_name%-*}" fi book_images_name="${book_images_name}-$i" - ((i++)) + i=$((i+1)) done mkdir -p "$book_path/${book_images_name}" @@ -543,7 +548,7 @@ HdlzToutiaoDownload() book_path="${book_path%-*}" fi book_path="${book_path}-$i" - ((i++)) + i=$((i+1)) done if ! book_images=($(LhhDownload -s -L -A "$getinfo_useragent" -H "referer: $signed_url" -H "cookie: ${toutiao_cookies[*]}" "https://www.toutiao.com/article/${id}" | grep -oP ']*>.*?' | grep -oP ']*src="\K[^"]*(?=")')) @@ -631,15 +636,15 @@ HdlzGetTouTiaoCookies() HdlzLhh() { - if [ ! -s "$ebooks_config" ] + if [ ! -s "$LIANHUANHUA_CONFIG" ] then - mkdir -p "$ebooks_root/" - printf '{"%s":{"%s":[]}}' "books" "hdlz" > "$ebooks_config" + mkdir -p "$LIANHUANHUA_ROOT/" + printf '{"%s":{"%s":[]}}' "books" "hdlz" > "$LIANHUANHUA_CONFIG" fi SetDelimiters -IFS=$'\003\t' read -r default_save_dir m_source m_id m_title m_cover m_excerpt m_behot_time m_downloaded m_fav < <(JQs flat "$ebooks_config" '' \ +IFS=$'\003\t' read -r default_save_dir m_source m_id m_title m_cover m_excerpt m_behot_time m_downloaded m_fav < <(JQs flat "$LIANHUANHUA_CONFIG" '' \ '(.default // ""| if (.|type == "string") then {} else . end) as $default | (.books.hdlz | if . == "" then {} else . end) as $hdlz | reduce ({save_dir}|keys_unsorted[]) as $key ([]; @@ -676,7 +681,7 @@ reduce ({source,id,title,cover,excerpt,behot_time,downloaded,fav}|keys_unsorted[ inquirer list_input_index "是否重新查询" lookup_options lookup_options_index fi - COOKIE_FILE="$ebooks_root/cookie_hdlz" + COOKIE_FILE="$LIANHUANHUA_ROOT/cookie_hdlz" if [ "$books_total" -eq 0 ] || [ "$lookup_options_index" -eq 1 ] || [ "$lookup_options_index" -eq 3 ] then @@ -745,7 +750,7 @@ reduce ({excerpt,id,image_url,title}|keys_unsorted[]) as $key ([]; do if [ "${book_excerpts[j]}" == "[图片]" ] then - ((book_images_count++)) + book_images_count=$((book_images_count+1)) elif [ "${book_excerpts[j]}" == "end" ] then if [ "${book_excerpts[j-1]}" == "[图片]" ] && [ -n "${book_images_command:-}" ] @@ -810,7 +815,7 @@ reduce ({excerpt,id,image_url,title}|keys_unsorted[]) as $key ([]; books="${books}${new_book}" done - ((loop++)) + loop=$((loop+1)) if [ "$paging_is_end" = true ] then @@ -824,9 +829,8 @@ reduce ({excerpt,id,image_url,title}|keys_unsorted[]) as $key ([]; continue fi - json=true jq_path='["books","hdlz"]' - JQ add "$ebooks_config" "[$books]" + JQ add "$LIANHUANHUA_CONFIG" "[$books]" done fi @@ -837,14 +841,14 @@ reduce ({excerpt,id,image_url,title}|keys_unsorted[]) as $key ([]; HdlzGetTouTiaoCookies - last_behot_time=$(date +%s) - for((i=0;i "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectConf() { echo && read -p "输入网址: " http_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpRedirectToHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpsRedirectConf() { echo && read -p "输入网址: " https_redirect_address - printf '%s' " server { - listen $server_https_port; +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsRedirectConf() { echo && read -p "输入网址: " http_https_redirect_address - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" <> "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } NginxAppendHttpHttpsConf() { - printf '%s' " server { +cat > "$nginx_prefix/conf/sites_available/$server_domain.conf" < "$nginx_prefix/conf/sites_available/$server_domain.conf" +EOF } diff --git a/src/nginx/config_mmproxy b/src/nginx/config_mmproxy index 4547e2c..e7d710f 100644 --- a/src/nginx/config_mmproxy +++ b/src/nginx/config_mmproxy @@ -5,24 +5,12 @@ then echo -en "0.0.0.0/0\n::/0\n" > ~/allowed-subnets.txt fi +GoInstall + if [[ ! -x $(command -v go-mmproxy) ]] then Println "$info 安装 go-mmproxy" - - GoInstall - go get github.com/path-network/go-mmproxy - - if [[ ! -x $(command -v go-mmproxy) ]] - then - export PATH="$PATH:$HOME/go/bin" - - if [ "$dist" == "rpm" ] - then - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.bash_profile - else - echo "export PATH=\$PATH:\$HOME/go/bin" >> ~/.profile - fi - fi + go install github.com/path-network/go-mmproxy@latest fi echo @@ -62,7 +50,10 @@ fi if [ "$mmproxy_name" == "ssh" ] then - Println "$tip 请确保已经设置 ssh 监听地址和端口" + Println "$tip 请之后将 nginx 分流 ssh 协议至 $mmproxy_listen, 并将 ssh 监听改为下面输入的地址和端口" +elif [ "$mmproxy_name" == "acme" ] +then + Println "$tip 请之后将 nginx 分流 acme 协议至 $mmproxy_listen" fi Println "$tip 比如: 127.0.0.1:2222" @@ -76,19 +67,22 @@ then reload=1 fi -echo "[Unit] +cat > /etc/systemd/system/mmproxy-"$mmproxy_name".service < "/etc/systemd/system/mmproxy-$mmproxy_name.service" +WantedBy=multi-user.target +EOF if [ "${reload:-0}" -eq 1 ] then @@ -100,20 +94,24 @@ else systemctl start "mmproxy-$mmproxy_name" fi -if [ ! -f ~/ip.sh ] +if [ ! -f "$HOME"/ip.sh ] then - echo "#!/bin/bash +cat > "$HOME"/ip.sh < ~/ip.sh +ip -6 route add local ::/0 dev lo table 100 +EOF chmod +x ~/ip.sh fi if [ ! -f /etc/rc.local ] then - echo "#!/bin/bash -$HOME/ip.sh" > /etc/rc.local +cat > /etc/rc.local <> /etc/rc.local @@ -124,10 +122,11 @@ chmod +x /etc/rc.local if [[ $(systemctl is-active rc-local) == "inactive" ]] then systemctl enable rc-local || true - if ! grep -q 'iif lo lookup 100' < <(ip rule list) - then - systemctl start rc-local || true - fi +fi + +if ! grep -q 'iif lo lookup 100' < <(ip rule list) +then + systemctl restart rc-local || true fi Println "$info mmproxy-$mmproxy_name 设置成功\n" diff --git a/src/nginx/install_cert b/src/nginx/sites_crt similarity index 58% rename from src/nginx/install_cert rename to src/nginx/sites_crt index 74d8ed4..a6f9fe0 100644 --- a/src/nginx/install_cert +++ b/src/nginx/sites_crt @@ -1,4 +1,4 @@ -NginxDomainInstallCert() +NginxSitesCertInstall() { local domain=$1 @@ -30,5 +30,34 @@ NginxDomainInstallCert() NginxDomainUpdateCrt "$domain" 1 - Println "$info $domain 证书安装成功" + Println "$info $domain 证书安装成功\n" +} + +NginxSitesCrtManage() +{ + if [ ! -d "$nginx_prefix"/conf/sites_crt ] + then + Println "$error 请先安装 $nginx_name\n" + return 1 + fi + + echo + crt_options=( '查看证书' '安装本地证书' '安装域名证书' ) + inquirer list_input_index "选择操作" crt_options crt_options_index + + case $crt_options_index in + 0) ServiceBrowse "$nginx_prefix"/conf/sites_crt + ;; + 1) + cd "$nginx_prefix"/conf/sites_crt + openssl genrsa -out localhost.key 2048 + openssl req -subj "/C=US/ST=NULL/L=NULL/O=NULL/OU=NULL/CN=NULL/emailAddress=NULL@example.com" -new -key localhost.key -out localhost.csr + openssl x509 -req -days 3650 -in localhost.csr -signkey localhost.key -out localhost.crt + Println "$info 本地证书安装成功\n" + ;; + 2) NginxConfigDomain + ;; + esac + + return 0 } diff --git a/src/nginx/update_ip b/src/nginx/update_ip index b95fe3c..263bddc 100644 --- a/src/nginx/update_ip +++ b/src/nginx/update_ip @@ -15,7 +15,8 @@ NginxUpdateIp() Println "$info 更新 ip ..." - printf '%s' "#!/bin/bash +cat > "$HOME"/update_cf_ibm_ip.sh < $nginx_prefix/conf/cloudflare_ip.conf; ibm_ips=( 50.22.0.0/16 @@ -37,20 +38,20 @@ ibm_ips=( 169.61.0.0/16 169.62.0.0/16 ) -for i in \"\${ibm_ips[@]}\"; do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; +for i in "\${ibm_ips[@]}"; do + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v4); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done for i in \$(curl https://www.cloudflare.com/ips-v6); do - echo \"set_real_ip_from \$i;\" >> $nginx_prefix/conf/cloudflare_ip.conf; + echo "set_real_ip_from \$i;" >> $nginx_prefix/conf/cloudflare_ip.conf; done echo >> $nginx_prefix/conf/cloudflare_ip.conf; echo '# use any of the following two' >> $nginx_prefix/conf/cloudflare_ip.conf; echo 'real_ip_header CF-Connecting-IP;' >> $nginx_prefix/conf/cloudflare_ip.conf; echo '#real_ip_header X-Forwarded-For;' >> $nginx_prefix/conf/cloudflare_ip.conf; -" > ~/update_cf_ibm_ip.sh +EOF bash ~/update_cf_ibm_ip.sh diff --git a/src/nx b/src/nx index 0112d49..ebc5309 100644 --- a/src/nx +++ b/src/nx @@ -1,120 +1,64 @@ Include utils/python "$@" - Include utils/crossplane "$@" - Include utils/openssl "$@" - Include utils/go "$@" - Include utils/postfix "$@" - Include utils/tesseract "$@" - Include utils/git "$@" - Include utils/nodejs "$@" - Include utils/mongodb "$@" - Include utils/dnscrypt "$@" - -Include src/nginx/install_cert "$@" - +Include utils/iperf "$@" Include src/nginx/view_status "$@" - Include src/nginx/toggle "$@" - Include src/nginx/restart "$@" - Include src/nginx/parse_config "$@" - Include src/nginx/get_config "$@" - Include src/nginx/list_domains "$@" - Include src/nginx/select_domain "$@" - Include src/nginx/list_domain "$@" - Include src/nginx/select_domain_server "$@" - Include src/nginx/config_domain "$@" - Include src/nginx/get_stream "$@" - Include src/nginx/list_stream "$@" - Include src/nginx/list_localhost "$@" - Include src/nginx/select_localhost_server "$@" - Include src/nginx/is_block_directive "$@" - Include src/nginx/input_args "$@" - Include src/nginx/add_directive "$@" - Include src/nginx/add_user "$@" - Include src/nginx/add_stream "$@" - Include src/nginx/add_http "$@" - Include src/nginx/add_rtmp "$@" - Include src/nginx/add_enabled "$@" - Include src/nginx/add_ssl "$@" - Include src/nginx/add_localhost "$@" - Include src/nginx/add_nodejs "$@" - Include src/nginx/add_cors "$@" - Include src/nginx/add_upstream_nodejs "$@" - Include src/nginx/add_flv "$@" - Include src/nginx/add_samesite_none "$@" - Include src/nginx/build_conf "$@" - Include src/nginx/check_localhost "$@" - Include src/nginx/config_directive "$@" - Include src/nginx/config_localhost "$@" - Include src/nginx/config_server "$@" - Include src/nginx/check_acme "$@" - Include src/nginx/update_cert "$@" - Include src/nginx/toggle_domain "$@" - Include src/nginx/delete_domain "$@" - Include src/nginx/delete_domain "$@" - Include src/nginx/rotate_log "$@" - Include src/nginx/update_ip "$@" - Include src/nginx/enable_domain "$@" - Include src/nginx/disable_domain "$@" - Include src/nginx/append_conf "$@" - Include src/nginx/add_domain "$@" - Include src/nginx/config_nodejs "$@" - Include src/nginx/menu_nodejs "$@" - Include src/nginx/menu_mongodb "$@" +Include src/nginx/sites_crt "$@" +Include src/service/browse "$@" NginxInstall() { @@ -418,7 +362,8 @@ NGINX_FILE="$nginx_prefix/sbin/nginx" if [ "$dist" != "mac" ] && [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then ResourceLimit - echo "[Unit] +cat > /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target" +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case ${1:-} in + e) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + l) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_logs=("$nginx_prefix"/logs/*) + shopt -u nullglob + + if [ -z "${nginx_logs:-}" ] + then + Println "$error 没有日志 !\n" + exit 1 + fi + + echo + inquirer list_input_index "选择日志文件" nginx_logs nginx_logs_index + + if [ "${2:-}" == "t" ] + then + tail -f "${nginx_logs[nginx_logs_index]}" + exit 0 + fi + editor "${nginx_logs[nginx_logs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " nginx 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -476,14 +479,16 @@ Println " nginx 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}16.${normal} 配置 postfix ${green}17.${normal} 配置 mmproxy ${green}18.${normal} 配置 dnscrypt proxy - ${green}19.${normal} 识别 cloudflare/ibm ip + ${green}19.${normal} 识别 ip ${green}20.${normal} 删除域名 ${green}21.${normal} 日志切割 + ${green}22.${normal} 证书管理 + ${green}23.${normal} 测速 ${tip} 输入: nx 打开面板 " -read -p "`gettext \"输入序号\"` [1-20]: " nginx_num +read -p "`gettext \"输入序号\"` [1-23]: " nginx_num case "$nginx_num" in 1) if [ -d "$nginx_prefix" ] @@ -557,7 +562,13 @@ case "$nginx_num" in 21) NginxLogRotate ;; - *) Println "$error $i18n_input_correct_number [1-20]\n" + 22) + NginxSitesCrtManage + ;; + 23) + IperfMenu + ;; + *) Println "$error $i18n_input_correct_number [1-23]\n" ;; esac diff --git a/src/or b/src/or index 37946c8..c3abed4 100644 --- a/src/or +++ b/src/or @@ -1,120 +1,63 @@ Include utils/python "$@" - Include utils/crossplane "$@" - Include utils/openssl "$@" - Include utils/go "$@" - Include utils/postfix "$@" - Include utils/tesseract "$@" - Include utils/git "$@" - Include utils/nodejs "$@" - Include utils/mongodb "$@" - Include utils/dnscrypt "$@" - -Include src/nginx/install_cert "$@" - +Include utils/iperf "$@" Include src/nginx/view_status "$@" - Include src/nginx/toggle "$@" - Include src/nginx/restart "$@" - Include src/nginx/parse_config "$@" - Include src/nginx/get_config "$@" - Include src/nginx/list_domains "$@" - Include src/nginx/select_domain "$@" - Include src/nginx/list_domain "$@" - Include src/nginx/select_domain_server "$@" - Include src/nginx/config_domain "$@" - Include src/nginx/get_stream "$@" - Include src/nginx/list_stream "$@" - Include src/nginx/list_localhost "$@" - Include src/nginx/select_localhost_server "$@" - Include src/nginx/is_block_directive "$@" - Include src/nginx/input_args "$@" - Include src/nginx/add_directive "$@" - Include src/nginx/add_user "$@" - Include src/nginx/add_stream "$@" - Include src/nginx/add_http "$@" - Include src/nginx/add_rtmp "$@" - Include src/nginx/add_enabled "$@" - Include src/nginx/add_ssl "$@" - Include src/nginx/add_localhost "$@" - Include src/nginx/add_nodejs "$@" - Include src/nginx/add_cors "$@" - Include src/nginx/add_upstream_nodejs "$@" - Include src/nginx/add_flv "$@" - Include src/nginx/add_samesite_none "$@" - Include src/nginx/build_conf "$@" - Include src/nginx/check_localhost "$@" - Include src/nginx/config_directive "$@" - Include src/nginx/config_localhost "$@" - Include src/nginx/config_server "$@" - Include src/nginx/check_acme "$@" - Include src/nginx/update_cert "$@" - Include src/nginx/toggle_domain "$@" - Include src/nginx/delete_domain "$@" - Include src/nginx/delete_domain "$@" - Include src/nginx/rotate_log "$@" - Include src/nginx/update_ip "$@" - Include src/nginx/enable_domain "$@" - Include src/nginx/disable_domain "$@" - Include src/nginx/append_conf "$@" - Include src/nginx/add_domain "$@" - Include src/nginx/config_nodejs "$@" - Include src/nginx/menu_nodejs "$@" - Include src/nginx/menu_mongodb "$@" +Include src/nginx/sites_crt "$@" OpenrestyInstall() { @@ -415,7 +358,8 @@ NGINX_FILE="$nginx_prefix/sbin/nginx" if [ "$dist" != "mac" ] && [ ! -s "/etc/systemd/system/$nginx_name.service" ] && [ -d "$nginx_prefix" ] then ResourceLimit - echo "[Unit] +cat > /etc/systemd/system/$nginx_name.service < /etc/systemd/system/$nginx_name.service +WantedBy=multi-user.target +EOF $NGINX_FILE -s stop 2> /dev/null || true systemctl daemon-reload systemctl enable "$nginx_name" systemctl start "$nginx_name" fi +case ${1:-} in + e) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_confs=("$nginx_prefix"/conf/sites_available/*) + shopt -u nullglob + + if [ -z "${nginx_confs:-}" ] + then + Println "$error 请先添加域名 !\n" + exit 1 + fi + + nginx_confs=( "$nginx_prefix"/conf/nginx.conf "${nginx_confs[@]}" ) + + echo + inquirer list_input_index "选择配置文件" nginx_confs nginx_confs_index + editor "${nginx_confs[nginx_confs_index]}" + exit 0 + ;; + l) + if [ ! -d "$nginx_prefix" ] + then + Println "$error 尚未安装, 请检查 !\n" + exit 1 + fi + + shopt -s nullglob + nginx_logs=("$nginx_prefix"/logs/*) + shopt -u nullglob + + if [ -z "${nginx_logs:-}" ] + then + Println "$error 没有日志 !\n" + exit 1 + fi + + echo + inquirer list_input_index "选择日志文件" nginx_logs nginx_logs_index + + if [ "${2:-}" == "t" ] + then + tail -f "${nginx_logs[nginx_logs_index]}" + exit 0 + fi + editor "${nginx_logs[nginx_logs_index]}" + exit 0 + ;; + *) + ;; +esac + Println " openresty 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}1.${normal} 安装 @@ -468,13 +470,15 @@ Println " openresty 管理面板 ${normal}${red}[v$sh_ver]${normal} ${green}12.${normal} 重启 ———————————— ${green}13.${normal} 配置 日志切割 - ${green}14.${normal} 识别 cloudflare/ibm ip + ${green}14.${normal} 识别 ip ${green}15.${normal} 删除域名 + ${green}16.${normal} 证书管理 + ${green}17.${normal} 测速 ${tip} 输入: or 打开面板 " -read -p "`gettext \"输入序号\"` [1-15]: " openresty_num +read -p "`gettext \"输入序号\"` [1-17]: " openresty_num case "$openresty_num" in 1) if [ -d "$nginx_prefix" ] @@ -530,7 +534,13 @@ case "$openresty_num" in 15) NginxDeleteDomain ;; - *) Println "$error $i18n_input_correct_number [1-15]\n" + 16) + NginxSitesCrtManage + ;; + 17) + IperfMenu + ;; + *) Println "$error $i18n_input_correct_number [1-17]\n" ;; esac diff --git a/src/rc b/src/rc new file mode 100644 index 0000000..984a220 --- /dev/null +++ b/src/rc @@ -0,0 +1,120 @@ +Include src/service/get "$@" +Include src/service/base64 "$@" +Include src/service/obscure "$@" +Include src/service/control "$@" +Include src/rclone/config "$@" +Include src/rclone/remote "$@" +Include src/rclone/mount "$@" +Include src/rclone/serve "$@" +Include src/rclone/sync "$@" +Include utils/openssl "$@" +Include utils/htpasswd "$@" + +echo +rclone_options=( '远端' '挂载' '服务' '服务账号' '同步' '安装/更新' ) +inquirer list_input_index "请选择" rclone_options rclone_options_index + +case $rclone_options_index in + 0) + echo + rclone_remote_options=( '查看' '添加' '修改' '删除' ) + inquirer list_input_index "选择操作" rclone_remote_options rclone_remote_options_index + + case $rclone_remote_options_index in + 0) RcloneRemoteView + ;; + 1) RcloneRemoteAdd + ;; + 2) RcloneRemoteEdit + ;; + 3) RcloneRemoteDel + ;; + esac + ;; + 1) + echo + rclone_mount_options=( '查看' '添加' '修改' '删除' '执行挂载' '取消挂载' ) + inquirer list_input_index "选择操作" rclone_mount_options rclone_mount_options_index + + case $rclone_mount_options_index in + 0) RcloneMountView + ;; + 1) RcloneMountAdd + ;; + 2) RcloneMountEdit + ;; + 3) RcloneMountDel + ;; + 4) RcloneMountExc + ;; + 5) RcloneMountDeExc + ;; + esac + ;; + 2) + echo + rclone_serve_options=( '查看' '添加' '修改' '删除' '执行服务' '取消服务' ) + inquirer list_input_index "选择操作" rclone_serve_options rclone_serve_options_index + + case $rclone_serve_options_index in + 0) RcloneServeView + ;; + 1) RcloneServeAdd + ;; + 2) RcloneServeEdit + ;; + 3) RcloneServeDel + ;; + 4) RcloneServeExc + ;; + 5) RcloneServeDeExc + ;; + esac + ;; + 3) + echo + rclone_serve_acc_options=( '查看' '添加' '修改' '删除' ) + inquirer list_input_index "选择操作" rclone_serve_acc_options rclone_serve_acc_options_index + + case $rclone_serve_acc_options_index in + 0) RcloneServeAccView + ;; + 1) RcloneServeAccAdd + ;; + 2) RcloneServeAccEdit + ;; + 3) RcloneServeAccDel + ;; + esac + ;; + 4) + echo + rclone_sync_options=( '查看' '添加' '修改' '删除' '执行' ) + inquirer list_input_index "选择操作" rclone_sync_options rclone_sync_options_index + + case $rclone_sync_options_index in + 0) RcloneSyncView + ;; + 1) RcloneSyncAdd + ;; + 2) RcloneSyncEdit + ;; + 3) RcloneSyncDel + ;; + 4) RcloneSyncExc + ;; + esac + ;; + 5) + if [[ -x $(command -v rclone) ]] + then + rclone selfupdate + else + if [ "$dist" == "mac" ] + then + Println "$tip 可能需要输入密码继续安装" + fi + sudo -v ; curl https://rclone.org/install.sh | grep -v 0555 | sudo bash + fi + ;; +esac diff --git a/src/rclone/config b/src/rclone/config new file mode 100644 index 0000000..7537f62 --- /dev/null +++ b/src/rclone/config @@ -0,0 +1,17 @@ +RcloneConfigUpdate() +{ + if [ -z "${rclone_remotes_count:-}" ] + then + ServiceGet rclone remote + fi + + if [ "$rclone_remotes_count" -gt 0 ] + then + local i rclone_config="" + for((i=0;i "$HOME/.config/rclone/rclone.conf" + fi +} diff --git a/src/rclone/mount b/src/rclone/mount new file mode 100644 index 0000000..c5ead81 --- /dev/null +++ b/src/rclone/mount @@ -0,0 +1,247 @@ +RcloneMountView() +{ + RcloneRemoteView + + echo + inquirer list_input_index "选择远端" rclone_remotes_options rclone_remotes_index + + if [ -z "${rclone_remotes_path[rclone_remotes_index]:-}" ] + then + Println "$error 请先添加挂载\n" + return 1 + fi + + IFS="${delimiters[1]}" read -r -a rclone_remote_paths <<< "${rclone_remotes_path[rclone_remotes_index]}" + IFS="${delimiters[1]}" read -r -a rclone_remote_mount_paths <<< "${rclone_remotes_mount_path[rclone_remotes_index]}" + + rclone_remote_mount_count=${#rclone_remote_paths[@]} + + rclone_remote_mount_options=() + local i rclone_remote_mount_list="" + + for((i=0;i ${rclone_remote_mount_paths[i]} ${green}(已挂载)${normal}") + else + rclone_remote_mount_list="${rclone_remote_mount_list}${green}$((i+1)).${normal} 远端路径: ${rclone_remote_paths[i]}\n挂载点: ${rclone_remote_mount_paths[i]}\n\n" + rclone_remote_mount_options+=("${rclone_remotes_name[rclone_remotes_index]}:${rclone_remote_paths[i]} -> ${rclone_remote_mount_paths[i]}") + fi + done + + Println "$rclone_remote_mount_list" +} + +RcloneMountAdd() +{ + RcloneRemoteView + + echo + inquirer list_input_index "选择远端" rclone_remotes_options rclone_remotes_index + + echo + ExitOnText "输入远端地址" rclone_remote_path + + echo + ExitOnText "输入挂载点" rclone_remote_mount_path + RemoveQuotes rclone_remote_mount_path + + new_mount=$( + $JQ_FILE -n --arg path "$rclone_remote_path" --arg mount_path "$rclone_remote_mount_path" \ + '{ + path: $path, + mount_path: $mount_path + }' + ) + + jq_path='["rclone","remote",'"$rclone_remotes_index"',"mount"]' + JQ add "$SERVICES_CONFIG" "[$new_mount]" + + Println "$info 挂载添加成功\n" +} + +RcloneMountEdit() +{ + RcloneMountView + + inquirer checkbox_input_indices "选择修改的挂载" rclone_remote_mount_options rclone_remote_mount_indices + + rclone_remote_mount_edit_options=( '远端路径' '挂载点' ) + + for rclone_remote_mount_index in "${rclone_remote_mount_indices[@]}" + do + echo "${rclone_remote_mount_options[rclone_remote_mount_index]}" + + echo + inquirer list_input_index "选择修改" rclone_remote_mount_edit_options rclone_remote_mount_edit_options_index + + if [ "$rclone_remote_mount_edit_options_index" == "0" ] + then + echo + inquirer text_input "输入新远端地址" rclone_remote_path "${rclone_remote_paths[rclone_remote_mount_index]}" + + if [ "$rclone_remote_path" != "${rclone_remote_paths[rclone_remote_mount_index]}" ] + then + jq_path='["rclone","remote",'"$rclone_remotes_index"',"mount",'"$rclone_remote_mount_index"',"path"]' + JQ update "$SERVICES_CONFIG" "$rclone_remote_path" + Println "$info 远端路径修改成功\n" + fi + else + echo + inquirer text_input "输入新挂载点" rclone_remote_mount_path "${rclone_remote_mount_paths[rclone_remote_mount_index]}" + if [ "$rclone_remote_mount_path" != "${rclone_remote_mount_paths[rclone_remote_mount_index]}" ] + then + jq_path='["rclone","remote",'"$rclone_remotes_index"',"mount",'"$rclone_remote_mount_index"',"mount_path"]' + JQ update "$SERVICES_CONFIG" "$rclone_remote_mount_path" + Println "$info 挂载点修改成功\n" + fi + fi + done + + return 0 +} + +RcloneMountDel() +{ + RcloneMountView + + Println "$tip 也将停止挂载" + inquirer checkbox_input_indices "选择删除的挂载" rclone_remote_mount_options rclone_remote_mount_indices + + local rclone_remote_mount_index_offset=0 i active_indices=() + + for((i=0;i ${rclone_remote_mount_paths[i]}" + ServiceControl start "rclone.mount.${rclone_remotes_name[rclone_remotes_index]}-$((i+1))" + done + fi + + Println "$info 挂载删除成功\n" +} + +RcloneMountExc() +{ + RcloneMountView + + if [ "$dist" == "mac" ] && [ ! -f /usr/local/lib/libfuse.dylib ] + then + DepInstall macfuse + fi + + inquirer checkbox_input_indices "选择执行的挂载" rclone_remote_mount_options rclone_remote_mount_indices + + RcloneConfigUpdate + + for rclone_remote_mount_index in "${rclone_remote_mount_indices[@]}" + do + rclone_remote_path="${rclone_remote_paths[rclone_remote_mount_index]}" + rclone_remote_mount_path="${rclone_remote_mount_paths[rclone_remote_mount_index]}" + rclone_mount_list="${rclone_remotes_name[rclone_remotes_index]}:$rclone_remote_path -> $rclone_remote_mount_path" + service_name="rclone.mount.${rclone_remotes_name[rclone_remotes_index]}-$((rclone_remote_mount_index+1))" + + if ServiceControl is-active "$service_name" + then + Println "$error $rclone_mount_list 已挂载\n" + continue + fi + + service_commands=( $(command -v rclone) mount ${rclone_remotes_name[rclone_remotes_index]}:$rclone_remote_path "$rclone_remote_mount_path" --allow-non-empty ) + + if ! err_msg=$(ServiceControl start "$service_name" service_commands) + then + Println "$error 挂载 $rclone_mount_list 失败, $err_msg\n" + continue + fi + + Println "$info 挂载 $rclone_mount_list 成功\n" + done +} + +RcloneMountDeExc() +{ + RcloneMountView + + inquirer checkbox_input_indices "选择取消的挂载" rclone_remote_mount_options rclone_remote_mount_indices + + for rclone_remote_mount_index in "${rclone_remote_mount_indices[@]}" + do + rclone_remote_path="${rclone_remote_paths[rclone_remote_mount_index]}" + rclone_remote_mount_path="${rclone_remote_mount_paths[rclone_remote_mount_index]}" + rclone_mount_list="${rclone_remotes_name[rclone_remotes_index]}:$rclone_remote_path -> $rclone_remote_mount_path" + service_name="rclone.mount.${rclone_remotes_name[rclone_remotes_index]}-$((rclone_remote_mount_index+1))" + + if ! ServiceControl is-active "$service_name" + then + Println "$error $rclone_mount_list 未挂载\n" + continue + fi + + Println "$info 正在取消挂载 $rclone_mount_list" + + if ! err_msg=$(ServiceControl stop "$service_name") + then + Println "$error 取消挂载 $rclone_mount_list 失败, $err_msg\n" + continue + fi + + Println "$info 取消挂载 $rclone_mount_list 成功\n" + done +} diff --git a/src/rclone/remote b/src/rclone/remote new file mode 100644 index 0000000..2c28ab5 --- /dev/null +++ b/src/rclone/remote @@ -0,0 +1,188 @@ +RcloneRemoteView() +{ + ServiceGet rclone remote + + if [ "$rclone_remotes_count" -eq 0 ] + then + Println "$error 请先添加 rclone 远端\n" + return 1 + fi + + rclone_remotes=() + rclone_remotes_options=() + + local i rclone_remotes_list="" rclone_remote_list="" + + for((i=0;i ${rclone_serve_addrs[*]}") + rclone_serves_list="${rclone_serves_list}${green}$((i+1)).${normal} 服务: ${rclone_serves_remote[i]}\n协议: ${rclone_serves_protocol[i]}\n监听: ${rclone_serve_addrs[*]}\n参数: ${rclone_serves_args[i]:-无}\n\n" + done + + Println "$rclone_serves_list" +} + +RcloneServeAddRemoteValidator() +{ + if [ "$1" == "$i18n_cancel" ] || [ "${1:0:1}" == "/" ] + then + return 0 + fi + + return 1 +} + +RcloneServeAddAddrValidator() +{ + if [ "${1:0:1}" == "/" ] || [ "${1:0:8}" == "unix:///" ] || [[ "$1" =~ ^[0-9.]*:[0-9]+ ]] + then + return 0 + fi + + return 1 +} + +RcloneServeAdd() +{ + ServiceGet rclone serve + + rclone_serve_options=( '本地' '远端' ) + echo + inquirer list_input_index "选择服务内容" rclone_serve_options rclone_serve_options_index + + if [ "$rclone_serve_options_index" -eq 0 ] + then + echo + ExitOnText "输入本地服务路径" rclone_serve_remote RcloneServeAddRemoteValidator + else + RcloneRemoteView + echo + inquirer list_input_index "选择服务的远端" rclone_remotes_options rclone_remotes_index + rclone_serve_remote="${rclone_remotes_name[rclone_remotes_index]}" + fi + + rclone_serve_protocol_options=( webdav nfs ) + echo + inquirer list_input "选择服务协议" rclone_serve_protocol_options rclone_serve_protocol + + rclone_serve_addrs=() + + while true + do + Println "$tip 比如 1.2.3.4:8000, :8080, :0(自动检测端口), unix:///path/to/socket. 如果使用 socket 或绝对路径, 连接验证将不可用" + inquirer text_input "输入监听地址 IP:PORT/socket/绝对路径" rclone_serve_addr :0 RcloneServeAddAddrValidator "地址格式错误" + + rclone_serve_addrs+=("$rclone_serve_addr") + + echo + inquirer list_input_index "是否继续添加监听地址" ny_options ny_index + + if [ "$ny_index" -eq 0 ] + then + break + fi + done + + while true + do + rclone_serve_htpasswd=$(RandStr) + if [ "$rclone_serves_count" -gt 0 ] && EleInArray "$rclone_serve_htpasswd" rclone_serves_htpasswd + then + continue + fi + break + done + + echo + inquirer text_input "输入服务参数" rclone_serve_args "$i18n_not_set" + + if [ "$rclone_serve_args" == "$i18n_not_set" ] + then + rclone_serve_args="" + fi + + new_serve=$( + $JQ_FILE -n --arg remote "$rclone_serve_remote" --arg protocol "$rclone_serve_protocol" \ + --argjson addr "$(ToJsonArray rclone_serve_addrs)" --arg htpasswd "$rclone_serve_htpasswd" \ + --arg args "$rclone_serve_args" \ + '{ + remote: $remote, + protocol: $protocol, + addr: $addr, + htpasswd: $htpasswd, + args: $args + }' + ) + + jq_path='["rclone","serve"]' + JQ add "$SERVICES_CONFIG" "[$new_serve]" + + Println "$info 服务添加成功\n" +} + +RcloneServeEdit() +{ + RcloneServeView + + inquirer checkbox_input_indices "选择修改的服务" rclone_serves_options rclone_serves_indices + + rclone_serve_edit_options=( '服务内容' '服务协议' '监听地址' '服务参数' ) + rclone_serve_options=( '本地' '远端' ) + rclone_serve_protocol_options=( webdav nfs ) + rclone_serve_addr_options=( '修改' '删除' ) + + for rclone_serves_index in "${rclone_serves_indices[@]}" + do + echo "${rclone_serves_options[rclone_serves_index]}" + + echo + inquirer checkbox_input_indices "选择修改" rclone_serve_edit_options rclone_serve_edit_options_indices + + for rclone_serve_edit_options_index in "${rclone_serve_edit_options_indices[@]}" + do + case $rclone_serve_edit_options_index in + 0) + echo + inquirer list_input_index "选择服务内容" rclone_serve_options rclone_serve_options_index + + if [ "$rclone_serve_options_index" -eq 0 ] + then + echo + ExitOnText "输入本地服务路径" rclone_serve_remote RcloneServeAddRemoteValidator + else + RcloneRemoteView + echo + inquirer list_input_index "选择服务的远端" rclone_remotes_options rclone_remotes_index + rclone_serve_remote="${rclone_remotes_name[rclone_remotes_index]}" + fi + + if [ "$rclone_serve_remote" != "${rclone_serves_remote[rclone_serves_index]}" ] + then + jq_path='["rclone","serve",'"$rclone_serves_index"',"remote"]' + JQ update "$SERVICES_CONFIG" "$rclone_serve_remote" + Println "$info 服务内容修改成功\n" + fi + ;; + 1) + echo + inquirer list_input "选择服务协议" rclone_serve_protocol_options rclone_serve_protocol + if [ "$rclone_serve_protocol" != "${rclone_serves_protocol[rclone_serves_index]}" ] + then + jq_path='["rclone","serve",'"$rclone_serves_index"',"protocol"]' + JQ update "$SERVICES_CONFIG" "$rclone_serve_protocol" + Println "$info 服务协议修改成功\n" + fi + ;; + 2) + rclone_serve_addr="${rclone_serves_addr[i]}" + IFS="${delimiters[0]}" read -r -a rclone_serve_addrs <<< "$rclone_serve_addr" + echo + inquirer checkbox_input_indices "选择监听地址" rclone_serve_addrs rclone_serve_addrs_indices + local rclone_serve_addrs_index_offset=0 + for rclone_serve_addrs_index in "${rclone_serve_addrs_indices[@]}" + do + echo + inquirer list_input_index "选择操作 ${rclone_serve_addrs[rclone_serve_addrs_index]}" rclone_serve_addr_options rclone_serve_addr_options_index + if [ "$rclone_serve_addr_options_index" -eq 0 ] + then + Println "$tip 比如 1.2.3.4:8000, :8080, :0(自动检测端口), unix:///path/to/socket. 如果使用 socket 或绝对路径, 连接验证将不可用" + inquirer text_input "输入新监听地址 IP:PORT/socket/绝对路径" rclone_serve_addr ${rclone_serve_addrs[rclone_serve_addrs_index]} RcloneServeAddAddrValidator "地址格式错误" + if [ "$rclone_serve_addr" != "${rclone_serve_addrs[rclone_serve_addrs_index]}" ] + then + jq_path='["rclone","serve",'"$rclone_serves_index"',"addr",'"$((rclone_serve_addrs_index-rclone_serve_addrs_index_offset))"']' + JQ update "$SERVICES_CONFIG" "$rclone_serve_addr" + Println "$info 监听地址修改成功\n" + fi + else + jq_path='["rclone","serve",'"$rclone_serves_index"',"addr",'"$((rclone_serve_addrs_index-rclone_serve_addrs_index_offset))"']' + JQ delete "$SERVICES_CONFIG" "$rclone_serve_addr" + rclone_serve_addrs_index_offset=$((rclone_serve_addrs_index_offset+1)) + Println "$info 监听地址删除成功\n" + fi + done + ;; + 3) + echo + inquirer text_input "输入服务参数" rclone_serve_args "${rclone_serves_args[rclone_serves_index]:-$i18n_not_set}" + if [ "$rclone_serve_args" == "${rclone_serves_args[rclone_serves_index]:-$i18n_not_set}" ] + then + continue + fi + jq_path='["rclone","serve",'"$rclone_serves_index"',"args"]' + JQ update "$SERVICES_CONFIG" "$rclone_serve_args" + Println "$info 服务参数修改成功\n" + ;; + esac + done + done + + return 0 +} + +RcloneServeDel() +{ + RcloneServeView + + Println "$tip 也将停止服务" + inquirer checkbox_input_indices "选择删除的服务" rclone_serves_options rclone_serves_indices + + local rclone_serves_index_offset=0 i active_indices=() + + for((i=0;i ${rclone_serve_addrs[*]}" + ServiceControl start "rclone.serve-$((i+1))" + done + fi + + Println "$info 服务删除成功\n" +} + +RcloneServeExc() +{ + RcloneServeView + + inquirer checkbox_input_indices "选择执行的服务" rclone_serves_options rclone_serves_indices + + RcloneConfigUpdate + + for rclone_serves_index in "${rclone_serves_indices[@]}" + do + service_name="rclone.serve-$((rclone_serves_index+1))" + rclone_serve_addr="${rclone_serves_addr[rclone_serves_index]}" + IFS="${delimiters[0]}" read -r -a rclone_serve_addrs <<< "$rclone_serve_addr" + rclone_serve_list="${rclone_serves_remote[rclone_serves_index]} -> ${rclone_serve_addrs[*]}" + + if ServiceControl is-active "$service_name" + then + Println "$error $rclone_serve_list 已运行\n" + continue + fi + + rclone_serve_accs_count=0 + + if [ -n "${rclone_serves_user[rclone_serves_index]:-}" ] + then + IFS="${delimiters[1]}" read -r -a rclone_serve_users <<< "${rclone_serves_user[rclone_serves_index]}" + IFS="${delimiters[1]}" read -r -a rclone_serve_passwords <<< "${rclone_serves_pass[rclone_serves_index]}" + + rclone_serve_accs_count=${#rclone_serve_users[@]} + fi + + service_commands=( $(command -v rclone) serve "${rclone_serves_protocol[rclone_serves_index]}" "${rclone_serves_remote[rclone_serves_index]}" ) + rclone_serve_auth=false + + for rclone_serve_addr in "${rclone_serve_addrs[@]}" + do + service_commands+=( --addr "$rclone_serve_addr" ) + + if [ "$rclone_serve_auth" = false ] && [[ "$rclone_serve_addr" =~ ^[0-9.]*:[0-9]+ ]] + then + rclone_serve_auth=true + fi + done + + if [ "${rclone_serves_protocol[rclone_serves_index]}" != "nfs" ] && [ "$rclone_serve_auth" = true ] && [ "$rclone_serve_accs_count" -gt 0 ] + then + if [ ! -f "$RCLONE_ROOT/serve/htpasswd/${rclone_serves_htpasswd[rclone_serves_index]}" ] + then + mkdir -p "$RCLONE_ROOT/serve/htpasswd" + htpasswd -Bbc "$RCLONE_ROOT/serve/htpasswd/${rclone_serves_htpasswd[rclone_serves_index]}" "${rclone_serve_users[0]}" "${rclone_serve_passwords[0]}" + for((i=1;i /dev/null | grep -q "pid ="; } + then + return 1 + fi + else + if ! EleInArray "$service_label" exceptions + then + service_label="aios.$service_label" + fi + service_file="/etc/systemd/system/${service_label}.service" + if [ ! -f "$service_file" ] || ! systemctl is-active --quiet "$service_label" + then + return 1 + fi + fi + return 0 +} + +ServiceControlIsEnabled() +{ + exceptions=( v2ray xray nginx openresty trojan dnscrypt-proxy ) + service_label="$1" + if [ "$dist" == "mac" ] + then + if ! EleInArray "$service_label" exceptions + then + service_label="com.aios.$service_label" + fi + service_file="$HOME/Library/LaunchAgents/${service_label}.plist" + if [ ! -f "$service_file" ] + then + return 1 + fi + else + if ! EleInArray "$service_label" exceptions + then + service_label="aios.$service_label" + fi + service_file="/etc/systemd/system/${service_label}.service" + if [ ! -f "$service_file" ] + then + return 1 + fi + fi + return 0 +} + +ServiceControlStart() +{ + if ServiceControlIsActive "$1" + then + echo "服务已启动" + return 0 + fi + + local var=("$2"[@]) + local args=() arg arr + + if [[ -n "${!var:-}" ]] + then + args=("${!var}") + if [[ ! -x "${args[0]}" ]] + then + echo "${args[0]} 不存在" + return 1 + fi + elif [ ! -f "$service_file" ] + then + echo "$service_file 不存在" + return 1 + fi + + if [ "$dist" == "mac" ] + then + if [ ! -f "$service_file" ] || [ -n "${3:-}" ] + then + arr="" + for arg in "${args[@]}" + do + arr="$arr\n $arg" + done + arr="$arr\n " + arr=$(echo -e "$arr") +cat > "$service_file" < + + + + Label + $service_label + ProgramArguments + $arr + RunAtLoad + + KeepAlive + + + +EOF + fi + launchctl load "$service_file" + else + if [ ! -f "$service_file" ] || [ -n "${3:-}" ] + then +cat > "$service_file" < /dev/null 2> /dev/null || true + rm -f /etc/systemd/system/"${service_label}".service + rm -f /lib/systemd/system/"${service_label}".service + rm -f /etc/init.d/"${service_label}" + fi +} + +ServiceControlRename() +{ + local old_service_label="$1" + local new_service_label="$2" + if [ "$dist" == "mac" ] + then + mv "$HOME/Library/LaunchAgents/com.aios.$old_service_label.plist" "$HOME/Library/LaunchAgents/com.aios.$new_service_label.plist" + else + mv "/etc/systemd/system/aios.$old_service_label.service" "/etc/systemd/system/aios.$new_service_label.service" + fi +} + +ServiceControl() +{ + local cmd=$1 + shift + case $cmd in + is-active) + ServiceControlIsActive "$@" + ;; + is-enabled) + ServiceControlIsEnabled "$@" + ;; + start) + ServiceControlStart "$@" + ;; + stop) + ServiceControlStop "$@" + ;; + restart) + ServiceControlRestart "$@" + ;; + disable) + ServiceControlDisable "$@" + ;; + rename) + ServiceControlRename "$@" + ;; + esac + return $? +} diff --git a/src/service/get b/src/service/get new file mode 100644 index 0000000..c29ad55 --- /dev/null +++ b/src/service/get @@ -0,0 +1,224 @@ +ServiceGet() +{ + JQInstall + + local service_id=$1 + + if [ ! -s "$SERVICES_CONFIG" ] + then + mkdir -p "$SERVICES_ROOT" + if [ -f "$IPTV_ROOT"/services.json ] + then + mv "$IPTV_ROOT"/services.json "$SERVICES_CONFIG" + else + printf '{"%s":{"%s":[]}}' "4gtv" "accounts" > "$SERVICES_CONFIG" + fi + fi + + SetDelimiters + + case $service_id in + 4gtv) + IFS=$'\003\t' read -r d_4gtv_proxy _4gtv_acc_email _4gtv_acc_pass _4gtv_acc_token < <(JQs flat "$SERVICES_CONFIG" '' ' + [(."'"$service_id"'".proxy // "") + "\u0003"] + ((."'"$service_id"'".accounts | if (.|type == "string") then {} else . end) as $accounts | + reduce ({email,password,token}|keys_unsorted[]) as $key ([]; + $accounts[$key] as $val | if $val then + . + [$val + "\u0002\u0003"] + else + . + ["\u0003"] + end + ))|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a _4gtv_accs_email <<< "$_4gtv_acc_email" + IFS="${delimiters[1]}" read -r -a _4gtv_accs_pass <<< "$_4gtv_acc_pass" + IFS="${delimiters[1]}" read -r -a _4gtv_accs_token <<< "$_4gtv_acc_token" + + _4gtv_accs_count=${#_4gtv_accs_email[@]} + ;; + alist) + IFS=$'\004\t' read -r alist_name alist_url alist_acc_username \ + alist_acc_password alist_acc_token < <(JQs flat "$SERVICES_CONFIG" '' ' + (."'"$service_id"'" | if (.|type == "string") then {} else . end) as $alist | + ($alist.accs // {} | if (.|type) == "string" then {} else . end) as $accs | + reduce ({name,url}|keys_unsorted[]) as $key ([]; + $alist[$key] as $val | if $val then + . + [$val + "\u0002\u0004"] + else + . + ["\u0004"] + end + ) + reduce ({username,password,token}|keys_unsorted[]) as $key ([]; + $accs[$key] as $val | if $val then + . + [$val + "\u0003\u0004"] + else + . + ["\u0004"] + end + )|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a alists_name <<< "$alist_name" + IFS="${delimiters[1]}" read -r -a alists_url <<< "$alist_url" + IFS="${delimiters[2]}" read -r -a alists_acc_username <<< "$alist_acc_username" + IFS="${delimiters[2]}" read -r -a alists_acc_password <<< "$alist_acc_password" + IFS="${delimiters[2]}" read -r -a alists_acc_token <<< "$alist_acc_token" + + alists_count=${#alists_name[@]} + ;; + rclone) + case ${2:-} in + serve) + IFS=$'\004\t' read -r m_serves_remote m_serves_protocol m_serves_addr m_serves_htpasswd \ + m_serves_args m_serves_user m_serves_pass < <(JQs flat "$SERVICES_CONFIG" '.[0].rclone.serve' ' + (if (.|type == "string") then {} else . end) as $serve | + ($serve.accs // {} | if (.|type) == "string" then {} else . end) as $accs | + reduce ({remote,protocol,addr,htpasswd,args}|keys_unsorted[]) as $key ([]; + $serve[$key] as $val | if $val then + . + [$val + "\u0002\u0004"] + else + . + ["\u0004"] + end + ) + reduce ({user,pass}|keys_unsorted[]) as $key ([]; + $accs[$key] as $val | if $val then + . + [$val + "\u0003\u0004"] + else + . + ["\u0004"] + end + )|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a rclone_serves_remote <<< "$m_serves_remote" + IFS="${delimiters[1]}" read -r -a rclone_serves_protocol <<< "$m_serves_protocol" + IFS="${delimiters[1]}" read -r -a rclone_serves_addr <<< "$m_serves_addr" + IFS="${delimiters[1]}" read -r -a rclone_serves_htpasswd <<< "$m_serves_htpasswd" + IFS="${delimiters[1]}" read -r -a rclone_serves_args <<< "$m_serves_args" + IFS="${delimiters[2]}" read -r -a rclone_serves_user <<< "$m_serves_user" + IFS="${delimiters[2]}" read -r -a rclone_serves_pass <<< "$m_serves_pass" + + rclone_serves_count=${#rclone_serves_remote[@]} + ;; + sync) + IFS=$'\004\t' read -r m_sync_rsync m_sync_source m_sync_target m_sync_args \ + m_sync_exclude_before m_sync_include m_sync_exclude_after < <(JQs flat "$SERVICES_CONFIG" '.[0].rclone.sync' ' + (if (type == "string") then {} else . end) as $sync | + reduce ({rsync,source,target,args,exclude_before,include,exclude_after}|keys_unsorted[]) as $key ([]; + $sync[$key] as $val | if $val then + . + [$val + "\u0002\u0004"] + else + . + ["\u0004"] + end + )|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a rclone_syncs_rsync <<< "$m_sync_rsync" + IFS="${delimiters[1]}" read -r -a rclone_syncs_source <<< "$m_sync_source" + IFS="${delimiters[1]}" read -r -a rclone_syncs_target <<< "$m_sync_target" + IFS="${delimiters[1]}" read -r -a rclone_syncs_args <<< "$m_sync_args" + IFS="${delimiters[1]}" read -r -a rclone_syncs_exclude_before <<< "$m_sync_exclude_before" + IFS="${delimiters[1]}" read -r -a rclone_syncs_include <<< "$m_sync_include" + IFS="${delimiters[1]}" read -r -a rclone_syncs_exclude_after <<< "$m_sync_exclude_after" + + rclone_syncs_count=${#rclone_syncs_rsync[@]} + ;; + *) + IFS=$'\004\t' read -r m_remotes_name m_remotes_type m_remotes_url \ + m_remotes_vendor m_remotes_user m_remotes_pass m_remotes_path m_remotes_mount_path < <(JQs flat "$SERVICES_CONFIG" '.[0].rclone.remote' ' + (if (.|type == "string") then {} else . end) as $remote | + ($remote.mount // {} | if (.|type) == "string" then {} else . end) as $mount | + reduce ({name,type,url,vendor,user,pass}|keys_unsorted[]) as $key ([]; + $remote[$key] as $val | if $val then + . + [$val + "\u0002\u0004"] + else + . + ["\u0004"] + end + ) + reduce ({path,mount_path}|keys_unsorted[]) as $key ([]; + $mount[$key] as $val | if $val then + . + [$val + "\u0003\u0004"] + else + . + ["\u0004"] + end + )|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a rclone_remotes_name <<< "$m_remotes_name" + IFS="${delimiters[1]}" read -r -a rclone_remotes_type <<< "$m_remotes_type" + IFS="${delimiters[1]}" read -r -a rclone_remotes_url <<< "$m_remotes_url" + IFS="${delimiters[1]}" read -r -a rclone_remotes_vendor <<< "$m_remotes_vendor" + IFS="${delimiters[1]}" read -r -a rclone_remotes_user <<< "$m_remotes_user" + IFS="${delimiters[1]}" read -r -a rclone_remotes_pass <<< "$m_remotes_pass" + IFS="${delimiters[2]}" read -r -a rclone_remotes_path <<< "$m_remotes_path" + IFS="${delimiters[2]}" read -r -a rclone_remotes_mount_path <<< "$m_remotes_mount_path" + + rclone_remotes_count=${#rclone_remotes_name[@]} + ;; + esac + ;; + kcc) + IFS="${delimiters[2]}"$'\t' read -r kcc_format kcc_process kcc_args kcc_output \ + m_source < <($JQ_FILE -r --arg delimiter "${delimiters[1]}" --arg delimiter2 "${delimiters[2]}" ' + (.kcc // {}) as $kcc | + reduce ({format,process,args,output,source}|keys_unsorted[]) as $key ([]; + $kcc[$key] as $val | ($val | type) as $type | if $val then + if ($type == "array") then + . + [($val|join($delimiter)) + $delimiter2] + else + . + [($val|tostring) + $delimiter2] + end + else + . + [$delimiter2] + end + )|@tsv' "$SERVICES_CONFIG") + + IFS="${delimiters[1]}" read -r -a kcc_sources <<< "$m_source" + ;; + iperf) + IFS=$'\004\t' read -r m_iperf_name m_iperf_type m_iperf_target \ + m_iperf_args < <(JQs flat "$SERVICES_CONFIG" '.[0].iperf' ' + (if (type == "string") then {} else . end) as $iperf | + reduce ({name,type,target,args}|keys_unsorted[]) as $key ([]; + $iperf[$key] as $val | if $val then + . + [$val + "\u0002\u0004"] + else + . + ["\u0004"] + end + )|@tsv' "${delimiters[@]}") + + IFS="${delimiters[1]}" read -r -a iperf_names <<< "$m_iperf_name" + IFS="${delimiters[1]}" read -r -a iperf_types <<< "$m_iperf_type" + IFS="${delimiters[1]}" read -r -a iperf_targets <<< "$m_iperf_target" + IFS="${delimiters[1]}" read -r -a iperf_args <<< "$m_iperf_args" + + iperf_count=${#iperf_types[@]} + ;; + *) + IFS=$'\003\t' read -r m_user_name m_phone_number m_password m_access_token m_device_no m_device_id m_refresh < <(JQs flat "$SERVICES_CONFIG" '' ' + (."'"$service_id"'".accounts | if (.|type == "string") then {} else . end) as $accounts | + reduce ({user_name,phone_number,password,access_token,device_no,device_id,refresh}|keys_unsorted[]) as $key ([]; + $accounts[$key] as $val | if $val then + . + [$val + "\u0002\u0003"] + else + . + ["\u0003"] + end + )|@tsv' "${delimiters[@]}") + + if [ -z "$m_user_name" ] + then + ts_accs_count=0 + return 0 + fi + + IFS="${delimiters[1]}" read -r -a ts_accs_user_name <<< "$m_user_name" + + if [ -z "$m_phone_number" ] + then + ts_accs_phone_number=("${ts_accs_user_name[@]//*/}") + else + IFS="${delimiters[1]}" read -r -a ts_accs_phone_number <<< "$m_phone_number" + fi + + IFS="${delimiters[1]}" read -r -a ts_accs_password <<< "$m_password" + IFS="${delimiters[1]}" read -r -a ts_accs_access_token <<< "$m_access_token" + IFS="${delimiters[1]}" read -r -a ts_accs_device_no <<< "$m_device_no" + IFS="${delimiters[1]}" read -r -a ts_accs_device_id <<< "$m_device_id" + IFS="${delimiters[1]}" read -r -a ts_accs_refresh <<< "$m_refresh" + + ts_accs_count=${#ts_accs_user_name[@]} + ;; + esac + + return 0 +} diff --git a/src/service/obscure b/src/service/obscure new file mode 100644 index 0000000..46feabf --- /dev/null +++ b/src/service/obscure @@ -0,0 +1,25 @@ +Obscure() +{ + OpensslInstall + + local hexkey="9c935b48730a554d6bfd7c63c886a92bd390198eb8128afbf4de162b8b95f638" + local hexiv=$(openssl rand -hex 16) + local buff=$(echo "$1" | openssl enc -aes-256-ctr -K "$hexkey" -iv "$hexiv") + hexiv=$(echo -n "$hexiv" | xxd -r -p) + local encrypted=$(echo -n "$hexiv$buff" | Base64urlEncode) + + echo "$encrypted" +} + +Deobscure() +{ + OpensslInstall + + local hexkey="9c935b48730a554d6bfd7c63c886a92bd390198eb8128afbf4de162b8b95f638" + local decoded=$(echo -n "$1" | Base64urlDecode) + local hexiv=$(echo -n "$decoded" | head -c 16 | hexdump -v -e '/1 "%02x"') # xxd -p + local buff=$(echo -n "$decoded" | tail -c +17) + local decrypted=$(echo -n "$buff" | openssl enc -aes-256-ctr -d -K "$hexkey" -iv "$hexiv" -nopad) + + echo "$decrypted" +} diff --git a/src/tv b/src/tv index 9466134..edffffc 100644 --- a/src/tv +++ b/src/tv @@ -1,222 +1,111 @@ -JQ_FILE="$IPTV_ROOT"/jq -FFMPEG_ROOT="$IPTV_ROOT" - Include utils/python "$@" - Include utils/ffmpeg "$@" - Include utils/youtube "$@" - Include utils/openssl "$@" - Include utils/pdf2html "$@" - Include utils/imagemagick "$@" - Include utils/imgcat "$@" - Include utils/git "$@" - Include utils/nodejs "$@" - Include utils/mongodb "$@" - Include src/iptv/filter_string "$@" - Include src/iptv/rand_name "$@" - Include src/iptv/sync_file "$@" - Include src/iptv/flv_creator "$@" - Include src/iptv/hls_creator "$@" - Include src/iptv/get_default "$@" - Include src/iptv/get_channels "$@" - Include src/iptv/list_channels "$@" - Include src/iptv/get_channel "$@" - Include src/iptv/list_channel "$@" - Include src/iptv/input_channels "$@" - Include src/iptv/view_channel "$@" - Include src/iptv/parse_hls "$@" - Include src/iptv/parse_youtube "$@" - Include src/iptv/parse_stream "$@" - Include src/iptv/set_stream "$@" - Include src/iptv/add_channel "$@" - Include src/iptv/edit_channel "$@" - Include src/iptv/menu_edit_channel "$@" - Include src/iptv/toggle_channel "$@" - Include src/iptv/check_xtream "$@" - Include src/iptv/start_channel "$@" - Include src/iptv/stop_channel "$@" - Include src/iptv/restart_channel "$@" - Include src/iptv/view_log "$@" - Include src/iptv/delete_channel "$@" - Include src/iptv/edit_default "$@" - Include src/iptv/list_schedule "$@" - Include src/iptv/parse_schedule "$@" - Include src/iptv/search_soccer "$@" - Include src/iptv/add_schedule "$@" - Include src/iptv/edit_schedule "$@" - Include src/iptv/sort_schedule "$@" - Include src/iptv/delete_schedule "$@" - Include src/iptv/menu_schedule "$@" - Include src/iptv/list_monitor "$@" - Include src/iptv/start_monitor "$@" - Include src/iptv/menu_monitor "$@" - Include src/iptv/menu_edit_default "$@" - -Include src/iptv/get_service "$@" - +Include src/service/get "$@" Include src/_4gtv/set_acc "$@" - Include src/_4gtv/reg_acc "$@" - Include src/_4gtv/list_accs "$@" - Include src/_4gtv/login_acc "$@" - Include src/_4gtv/list_acc "$@" - Include src/_4gtv/edit_acc "$@" - Include src/_4gtv/del_acc "$@" - Include src/_4gtv/get_acc_token "$@" - Include src/_4gtv/use_proxy "$@" - Include src/_4gtv/cron "$@" - Include src/_4gtv/enable_cron "$@" - Include src/_4gtv/disable_cron "$@" - Include src/_4gtv/add_link "$@" - Include src/_4gtv/start_link "$@" - Include src/xtream_codes/get_domains "$@" - Include src/xtream_codes/get_channels "$@" - Include src/xtream_codes/add_account "$@" - Include src/xtream_codes/verify_mac "$@" - Include src/xtream_codes/list "$@" - Include src/xtream_codes/list_account "$@" - Include src/xtream_codes/test_account "$@" - Include src/xtream_codes/list_mac "$@" - Include src/xtream_codes/search_channels "$@" - Include src/xtream_codes/list_channels "$@" - Include src/xtream_codes/add_mac "$@" - Include src/vip/set_host "$@" - Include src/vip/add_host "$@" - Include src/vip/edit_host "$@" - Include src/vip/get_hosts "$@" - Include src/vip/list_hosts "$@" - Include src/vip/delete_host "$@" - Include src/vip/set_user "$@" - Include src/vip/add_user "$@" - Include src/vip/edit_user "$@" - Include src/vip/get_users "$@" - Include src/vip/list_users "$@" - Include src/vip/list_user "$@" - Include src/vip/delete_user "$@" - Include src/vip/set_channel "$@" - Include src/vip/add_channel "$@" - Include src/vip/deploy_channel "$@" - Include src/vip/edit_channel "$@" - Include src/vip/list_channels "$@" - Include src/vip/get_stream "$@" - Include src/vip/list_channel "$@" - Include src/vip/delete_channel "$@" - Include src/vip/get_config "$@" - Include src/vip/set_public "$@" - Include src/vip/process_lists "$@" - Include src/vip/get_schedules "$@" - Include src/vip/monitor "$@" - Include src/vip/enable "$@" - Include src/vip/disable "$@" - Include src/vip/list_user_channel "$@" - Include src/vip/verify_license "$@" - Include src/iptv/menu_vip_user "$@" - Include src/iptv/menu_vip "$@" - Include src/iptv/menu_iptv "$@" - Include src/iptv/usage "$@" Install() @@ -541,7 +430,7 @@ then curl) Include src/iptv/cmd_curl "$@" ;; - b) + b|backup) Include src/iptv/cmd_backup "$@" ;; *) diff --git a/src/v2 b/src/v2 index 9022546..70c4fc4 100644 --- a/src/v2 +++ b/src/v2 @@ -1,318 +1,54 @@ Include utils/imagemagick "$@" - Include utils/imgcat "$@" - Include src/v2ray/get_free_tag "$@" - Include src/v2ray/view_staus "$@" - Include src/v2ray/set_bound "$@" - Include src/v2ray/add_inbound "$@" - Include src/v2ray/get_inbounds "$@" - Include src/v2ray/list_inbounds "$@" - Include src/v2ray/select_inbound "$@" - Include src/v2ray/select_account "$@" - Include src/v2ray/delete_inbound "$@" - Include src/v2ray/add_inbound_account "$@" - Include src/v2ray/list_inbound_accounts "$@" - Include src/v2ray/list_inbound_share "$@" - Include src/v2ray/delete_inbound_account "$@" - Include src/v2ray/add_outbound "$@" - Include src/v2ray/get_outbounds "$@" - Include src/v2ray/list_outbounds "$@" - Include src/v2ray/select_outbound "$@" - Include src/v2ray/delete_outbound "$@" - Include src/v2ray/add_outbound_account "$@" - Include src/v2ray/list_outbound_accounts "$@" - Include src/v2ray/delete_outbound_account "$@" - Include src/v2ray/get_routing "$@" - Include src/v2ray/list_routing "$@" - Include src/v2ray/set_routing "$@" - Include src/v2ray/get_policy "$@" - Include src/v2ray/list_policy "$@" - Include src/v2ray/set_policy "$@" - Include src/v2ray/get_reverse "$@" - Include src/v2ray/list_reverse "$@" - Include src/v2ray/set_reverse "$@" - Include src/v2ray/get_dns "$@" - Include src/v2ray/list_dns "$@" - Include src/v2ray/set_dns "$@" - Include src/v2ray/get_stats "$@" - Include src/v2ray/get_traffic "$@" - Include src/v2ray/list_stats "$@" - Include src/v2ray/reset_stats "$@" - Include src/v2ray/list_inbound_domains "$@" - Include src/v2ray/update_cert "$@" - Include src/v2ray/list_nginx_domains "$@" - Include src/v2ray/select_nginx_domain "$@" - Include src/v2ray/select_nginx_server "$@" - Include src/v2ray/update_nginx_cert "$@" - Include src/v2ray/add_nginx_proxy "$@" - Include src/v2ray/select_nginx_proxy "$@" - Include src/v2ray/list_nginx_domain "$@" - Include src/v2ray/config_domain "$@" - -V2rayInstall() -{ - if [ -s "$V2_CONFIG" ] - then - Println "$error $v2ray_name 已存在...\n" - ExitOnList n "`gettext \"是否覆盖原安装\"`" - fi - - DepsCheck - JQInstall - - if ! grep -q "$v2ray_name:" < "/etc/passwd" - then - if grep -q '\--group ' < <(adduser --help) - then - adduser $v2ray_name --system --group --no-create-home > /dev/null - else - adduser $v2ray_name --system --no-create-home > /dev/null - fi - usermod -s /usr/sbin/nologin $v2ray_name - fi - - Println "$info 安装 $v2ray_name..." - - if [ "$v2ray_name" == "v2ray" ] - then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - fi - - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" - - mkdir -p /var/log/$v2ray_name/ - [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log - chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ - chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ - - V2rayConfigUpdate - - systemctl daemon-reload - systemctl enable $v2ray_name - systemctl start $v2ray_name - - Println "$info $v2ray_name 安装完成\n" -} - -V2rayUpdate() -{ - DepsCheck - JQInstall - ShFileUpdate $v2ray_name - - if ! grep -q "$v2ray_name:" < "/etc/passwd" - then - if grep -q '\--group ' < <(adduser --help) - then - adduser $v2ray_name --system --group --no-create-home > /dev/null - else - adduser $v2ray_name --system --no-create-home > /dev/null - fi - usermod -s /usr/sbin/nologin $v2ray_name - fi - - if [ "$v2ray_name" == "v2ray" ] - then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - fi - - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" - - mkdir -p /var/log/$v2ray_name/ - [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log - chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ - chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ - - V2rayConfigUpdate - - systemctl daemon-reload - systemctl restart $v2ray_name - - Println "$info $v2ray_name 升级完成\n" -} - -V2rayConfigUpdate() -{ - if [ ! -e "$V2_CONFIG" ] - then - Println "$error $v2ray_name 未安装...\n" - exit 1 - fi - - if ! outbounds=$($JQ_FILE '.outbounds' "$V2_CONFIG" 2> /dev/null) || [ "$outbounds" == "null" ] - then - if grep -q '"path": "' < "$V2_CONFIG" - then - while IFS= read -r line - do - if [[ $line == *"path"* ]] - then - path=${line#*: \"} - path=${path%\"*} - break - fi - done < "$V2_CONFIG" - fi - - printf -v update_date '%(%m-%d-%H:%M:%S)T' -1 - cp -f "$V2_CONFIG" "${V2_CONFIG}_$update_date" - while IFS= read -r line - do - if [[ $line == *"port"* ]] - then - port=${line#*: } - port=${port%,*} - elif [[ $line == *"id"* ]] - then - id=${line#*: \"} - id=${id%\"*} - break - fi - done < "$V2_CONFIG" - - $JQ_FILE -n --arg port "${port:-$(GetFreePort)}" --arg id "${id:-$($V2CTL_FILE uuid)}" --arg path "${path:-/$(RandStr)}" \ - --arg error "/var/log/$v2ray_name/error.log" \ - '{ - "log": { - "access": "none", - "error": $error, - "loglevel": "error" - }, - "inbounds": [ - { - "listen": "127.0.0.1", - "port": $port | tonumber, - "protocol": "vmess", - "settings": { - "clients": [ - { - "id": $id, - "level": 0, - "alterId": 64, - "email": "name@localhost" - } - ] - }, - "streamSettings": { - "network": "ws", - "wsSettings": { - "path": $path - } - }, - "tag": "nginx-1" - } - ], - "outbounds": [ - { - "protocol": "freedom", - "tag": "direct" - }, - { - "protocol": "blackhole", - "tag": "block" - } - ], - "policy": { - "levels": { - "0": { - "handshake": 4, - "connIdle": 300, - "uplinkOnly": 2, - "downlinkOnly": 5, - "statsUserUplink": false, - "statsUserDownlink": false, - "bufferSize": 512 - } - }, - "system": { - "statsInboundUplink": false, - "statsInboundDownlink": false, - "statsOutboundUplink": false, - "statsOutboundDownlink": false - } - } - }' > "$V2_CONFIG" - - Println "$info $v2ray_name 配置文件已更新\n" - fi -} +Include src/v2ray/install "$@" +Include src/service/control "$@" ShFileCheck @@ -322,11 +58,8 @@ tls_name="TLS" if [ -d /etc/v2ray/ ] && [ ! -d /usr/local/etc/v2ray/ ] then - systemctl disable v2ray --now > /dev/null 2> /dev/null || true + ServiceControlDisable disable v2ray rm -rf /usr/bin/v2ray/ - rm -f /etc/systemd/system/v2ray.service - rm -f /lib/systemd/system/v2ray.service - rm -f /etc/init.d/v2ray mv /etc/v2ray/ /usr/local/etc/ if ! grep -q "v2ray:" < "/etc/passwd" then @@ -343,8 +76,6 @@ then chown -R v2ray:v2ray /var/log/v2ray/ chown -R v2ray:v2ray /usr/local/share/v2ray/ V2rayUpdate - systemctl enable v2ray - systemctl start v2ray fi Include src/v2ray/menu "$@" diff --git a/src/v2ray/install b/src/v2ray/install new file mode 100644 index 0000000..a8ed916 --- /dev/null +++ b/src/v2ray/install @@ -0,0 +1,214 @@ +V2rayInstall() +{ + if [ -s "$V2_CONFIG" ] + then + Println "$error $v2ray_name 已存在...\n" + ExitOnList n "`gettext \"是否覆盖原安装\"`" + fi + + DepsCheck + JQInstall + + if ! grep -q "$v2ray_name:" < "/etc/passwd" + then + if grep -q '\--group ' < <(adduser --help) + then + adduser $v2ray_name --system --group --no-create-home > /dev/null + else + adduser $v2ray_name --system --no-create-home > /dev/null + fi + usermod -s /usr/sbin/nologin $v2ray_name + fi + + Println "$info 安装 $v2ray_name..." + + if [ "$v2ray_name" == "v2ray" ] + then + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + else + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + fi + + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" + + mkdir -p /var/log/$v2ray_name/ + [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log + chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ + chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ + + V2rayConfigUpdate + + ServiceControl start $v2ray_name + + Println "$info $v2ray_name 安装完成\n" +} + +V2rayUpdate() +{ + DepsCheck + JQInstall + ShFileUpdate $v2ray_name + + if ! grep -q "$v2ray_name:" < "/etc/passwd" + then + if grep -q '\--group ' < <(adduser --help) + then + adduser $v2ray_name --system --group --no-create-home > /dev/null + else + adduser $v2ray_name --system --no-create-home > /dev/null + fi + usermod -s /usr/sbin/nologin $v2ray_name + fi + + if [ "$v2ray_name" == "v2ray" ] + then + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + else + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + fi + + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" + + mkdir -p /var/log/$v2ray_name/ + [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log + chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ + chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ + + V2rayConfigUpdate + + ServiceControl restart $v2ray_name + + Println "$info $v2ray_name 升级完成\n" +} + +V2rayConfigUpdate() +{ + if [ ! -e "$V2_CONFIG" ] + then + Println "$error $v2ray_name 未安装...\n" + exit 1 + fi + + if ! outbounds=$($JQ_FILE '.outbounds' "$V2_CONFIG" 2> /dev/null) || [ "$outbounds" == "null" ] + then + if grep -q '"path": "' < "$V2_CONFIG" + then + while IFS= read -r line + do + if [[ $line == *"path"* ]] + then + path=${line#*: \"} + path=${path%\"*} + break + fi + done < "$V2_CONFIG" + fi + + printf -v update_date '%(%m-%d-%H:%M:%S)T' -1 + cp -f "$V2_CONFIG" "${V2_CONFIG}_$update_date" + while IFS= read -r line + do + if [[ $line == *"port"* ]] + then + port=${line#*: } + port=${port%,*} + elif [[ $line == *"id"* ]] + then + id=${line#*: \"} + id=${id%\"*} + break + fi + done < "$V2_CONFIG" + + $JQ_FILE -n --arg port "${port:-$(GetFreePort)}" --arg id "${id:-$($V2CTL_FILE uuid)}" --arg path "${path:-/$(RandStr)}" \ + --arg error "/var/log/$v2ray_name/error.log" \ + '{ + "log": { + "access": "none", + "error": $error, + "loglevel": "error" + }, + "inbounds": [ + { + "listen": "127.0.0.1", + "port": $port | tonumber, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": $id, + "level": 0, + "alterId": 64, + "email": "name@localhost" + } + ] + }, + "streamSettings": { + "network": "ws", + "wsSettings": { + "path": $path + } + }, + "tag": "nginx-1" + } + ], + "outbounds": [ + { + "protocol": "freedom", + "tag": "direct" + }, + { + "protocol": "blackhole", + "tag": "block" + } + ], + "policy": { + "levels": { + "0": { + "handshake": 4, + "connIdle": 300, + "uplinkOnly": 2, + "downlinkOnly": 5, + "statsUserUplink": false, + "statsUserDownlink": false, + "bufferSize": 512 + } + }, + "system": { + "statsInboundUplink": false, + "statsInboundDownlink": false, + "statsOutboundUplink": false, + "statsOutboundDownlink": false + } + } + }' > "$V2_CONFIG" + + Println "$info $v2ray_name 配置文件已更新\n" + fi +} diff --git a/src/v2ray/list_inbound_share b/src/v2ray/list_inbound_share index 7ffc87d..b8bbeaf 100644 --- a/src/v2ray/list_inbound_share +++ b/src/v2ray/list_inbound_share @@ -35,11 +35,7 @@ V2rayListInboundShare() then ImgcatInstall fi - if [[ ! -x $(command -v convert) ]] - then - Println "$info 安装 ImageMagick" - ImageMagickInstall - fi + ImageMagickInstall DepInstall qrencode qrencode -s 1 -o "$HOME/vmess_link.png" "vmess://$vmess_link" /usr/local/bin/imgcat --half-height "$HOME/vmess_link.png" diff --git a/src/v2ray/menu b/src/v2ray/menu index 7932ab0..56a4740 100644 --- a/src/v2ray/menu +++ b/src/v2ray/menu @@ -72,7 +72,6 @@ case $v2ray_num in ;; 2) V2rayUpdate - systemctl restart $v2ray_name ;; 3) V2rayConfigUpdate diff --git a/src/x b/src/x index 49fba56..6805e1b 100644 --- a/src/x +++ b/src/x @@ -1,318 +1,54 @@ Include utils/imagemagick "$@" - Include utils/imgcat "$@" - Include src/v2ray/get_free_tag "$@" - Include src/v2ray/view_staus "$@" - Include src/v2ray/set_bound "$@" - Include src/v2ray/add_inbound "$@" - Include src/v2ray/get_inbounds "$@" - Include src/v2ray/list_inbounds "$@" - Include src/v2ray/select_inbound "$@" - Include src/v2ray/select_account "$@" - Include src/v2ray/delete_inbound "$@" - Include src/v2ray/add_inbound_account "$@" - Include src/v2ray/list_inbound_accounts "$@" - Include src/v2ray/list_inbound_share "$@" - Include src/v2ray/delete_inbound_account "$@" - Include src/v2ray/add_outbound "$@" - Include src/v2ray/get_outbounds "$@" - Include src/v2ray/list_outbounds "$@" - Include src/v2ray/select_outbound "$@" - Include src/v2ray/delete_outbound "$@" - Include src/v2ray/add_outbound_account "$@" - Include src/v2ray/list_outbound_accounts "$@" - Include src/v2ray/delete_outbound_account "$@" - Include src/v2ray/get_routing "$@" - Include src/v2ray/list_routing "$@" - Include src/v2ray/set_routing "$@" - Include src/v2ray/get_policy "$@" - Include src/v2ray/list_policy "$@" - Include src/v2ray/set_policy "$@" - Include src/v2ray/get_reverse "$@" - Include src/v2ray/list_reverse "$@" - Include src/v2ray/set_reverse "$@" - Include src/v2ray/get_dns "$@" - Include src/v2ray/list_dns "$@" - Include src/v2ray/set_dns "$@" - Include src/v2ray/get_stats "$@" - Include src/v2ray/get_traffic "$@" - Include src/v2ray/list_stats "$@" - Include src/v2ray/reset_stats "$@" - Include src/v2ray/list_inbound_domains "$@" - Include src/v2ray/update_cert "$@" - Include src/v2ray/list_nginx_domains "$@" - Include src/v2ray/select_nginx_domain "$@" - Include src/v2ray/select_nginx_server "$@" - Include src/v2ray/update_nginx_cert "$@" - Include src/v2ray/add_nginx_proxy "$@" - Include src/v2ray/select_nginx_proxy "$@" - Include src/v2ray/list_nginx_domain "$@" - Include src/v2ray/config_domain "$@" - -V2rayInstall() -{ - if [ -s "$V2_CONFIG" ] - then - Println "$error $v2ray_name 已存在...\n" - ExitOnList n "`gettext \"是否覆盖原安装\"`" - fi - - DepsCheck - JQInstall - - if ! grep -q "$v2ray_name:" < "/etc/passwd" - then - if grep -q '\--group ' < <(adduser --help) - then - adduser $v2ray_name --system --group --no-create-home > /dev/null - else - adduser $v2ray_name --system --no-create-home > /dev/null - fi - usermod -s /usr/sbin/nologin $v2ray_name - fi - - Println "$info 安装 $v2ray_name..." - - if [ "$v2ray_name" == "v2ray" ] - then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - fi - - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" - - mkdir -p /var/log/$v2ray_name/ - [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log - chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ - chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ - - V2rayConfigUpdate - - systemctl daemon-reload - systemctl enable $v2ray_name - systemctl start $v2ray_name - - Println "$info $v2ray_name 安装完成\n" -} - -V2rayUpdate() -{ - DepsCheck - JQInstall - ShFileUpdate $v2ray_name - - if ! grep -q "$v2ray_name:" < "/etc/passwd" - then - if grep -q '\--group ' < <(adduser --help) - then - adduser $v2ray_name --system --group --no-create-home > /dev/null - else - adduser $v2ray_name --system --no-create-home > /dev/null - fi - usermod -s /usr/sbin/nologin $v2ray_name - fi - - if [ "$v2ray_name" == "v2ray" ] - then - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - else - { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ - | sed "s+nobody+$v2ray_name+g" \ - | sed "s+ 'sha1'++g" \ - | sed "s+ 'sha256'++g" \ - | sed "s+ 'sha512'++g" \ - | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ - | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash - fi - - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" - sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" - - mkdir -p /var/log/$v2ray_name/ - [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log - chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ - chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ - - V2rayConfigUpdate - - systemctl daemon-reload - systemctl restart $v2ray_name - - Println "$info $v2ray_name 升级完成\n" -} - -V2rayConfigUpdate() -{ - if [ ! -e "$V2_CONFIG" ] - then - Println "$error $v2ray_name 未安装...\n" - exit 1 - fi - - if ! outbounds=$($JQ_FILE '.outbounds' "$V2_CONFIG" 2> /dev/null) || [ "$outbounds" == "null" ] - then - if grep -q '"path": "' < "$V2_CONFIG" - then - while IFS= read -r line - do - if [[ $line == *"path"* ]] - then - path=${line#*: \"} - path=${path%\"*} - break - fi - done < "$V2_CONFIG" - fi - - printf -v update_date '%(%m-%d-%H:%M:%S)T' -1 - cp -f "$V2_CONFIG" "${V2_CONFIG}_$update_date" - while IFS= read -r line - do - if [[ $line == *"port"* ]] - then - port=${line#*: } - port=${port%,*} - elif [[ $line == *"id"* ]] - then - id=${line#*: \"} - id=${id%\"*} - break - fi - done < "$V2_CONFIG" - - $JQ_FILE -n --arg port "${port:-$(GetFreePort)}" --arg id "${id:-$($V2CTL_FILE uuid)}" --arg path "${path:-/$(RandStr)}" \ - --arg error "/var/log/$v2ray_name/error.log" \ - '{ - "log": { - "access": "none", - "error": $error, - "loglevel": "error" - }, - "inbounds": [ - { - "listen": "127.0.0.1", - "port": $port | tonumber, - "protocol": "vmess", - "settings": { - "clients": [ - { - "id": $id, - "level": 0, - "alterId": 64, - "email": "name@localhost" - } - ] - }, - "streamSettings": { - "network": "ws", - "wsSettings": { - "path": $path - } - }, - "tag": "nginx-1" - } - ], - "outbounds": [ - { - "protocol": "freedom", - "tag": "direct" - }, - { - "protocol": "blackhole", - "tag": "block" - } - ], - "policy": { - "levels": { - "0": { - "handshake": 4, - "connIdle": 300, - "uplinkOnly": 2, - "downlinkOnly": 5, - "statsUserUplink": false, - "statsUserDownlink": false, - "bufferSize": 512 - } - }, - "system": { - "statsInboundUplink": false, - "statsInboundDownlink": false, - "statsOutboundUplink": false, - "statsOutboundDownlink": false - } - } - }' > "$V2_CONFIG" - - Println "$info $v2ray_name 配置文件已更新\n" - fi -} +Include src/xray/install "$@" +Include src/service/control "$@" ShFileCheck @@ -323,6 +59,6 @@ V2_FILE="/usr/local/bin/x" V2_LINK="https://raw.githubusercontent.com/XTLS/Xray-install/main/install-release.sh" V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xray_install-release.sh" V2CTL_FILE="/usr/local/bin/xray" -V2_CONFIG="/usr/local/etc/xray/config.json" +V2_CONFIG="$X_CONFIG" Include src/v2ray/menu "$@" diff --git a/src/xray/install b/src/xray/install new file mode 100644 index 0000000..a8ed916 --- /dev/null +++ b/src/xray/install @@ -0,0 +1,214 @@ +V2rayInstall() +{ + if [ -s "$V2_CONFIG" ] + then + Println "$error $v2ray_name 已存在...\n" + ExitOnList n "`gettext \"是否覆盖原安装\"`" + fi + + DepsCheck + JQInstall + + if ! grep -q "$v2ray_name:" < "/etc/passwd" + then + if grep -q '\--group ' < <(adduser --help) + then + adduser $v2ray_name --system --group --no-create-home > /dev/null + else + adduser $v2ray_name --system --no-create-home > /dev/null + fi + usermod -s /usr/sbin/nologin $v2ray_name + fi + + Println "$info 安装 $v2ray_name..." + + if [ "$v2ray_name" == "v2ray" ] + then + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + else + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + fi + + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" + + mkdir -p /var/log/$v2ray_name/ + [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log + chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ + chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ + + V2rayConfigUpdate + + ServiceControl start $v2ray_name + + Println "$info $v2ray_name 安装完成\n" +} + +V2rayUpdate() +{ + DepsCheck + JQInstall + ShFileUpdate $v2ray_name + + if ! grep -q "$v2ray_name:" < "/etc/passwd" + then + if grep -q '\--group ' < <(adduser --help) + then + adduser $v2ray_name --system --group --no-create-home > /dev/null + else + adduser $v2ray_name --system --no-create-home > /dev/null + fi + usermod -s /usr/sbin/nologin $v2ray_name + fi + + if [ "$v2ray_name" == "v2ray" ] + then + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/v2fly/v2ray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/v2fly/v2ray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + else + { curl -s -m 10 "$V2_LINK" || curl -s -m 30 "$V2_LINK_FALLBACK"; } \ + | sed "s+nobody+$v2ray_name+g" \ + | sed "s+ 'sha1'++g" \ + | sed "s+ 'sha256'++g" \ + | sed "s+ 'sha512'++g" \ + | sed "s+https://api.github.com/repos/XTLS/Xray-core/releases/latest+$FFMPEG_MIRROR_LINK/$v2ray_name.json+g" \ + | sed "s+https://github.com/XTLS/Xray-core/releases/download+$FFMPEG_MIRROR_LINK/$v2ray_name+g" | bash + fi + + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name.service" + sed -i "s+nobody+$v2ray_name+g" "/etc/systemd/system/$v2ray_name@.service" + + mkdir -p /var/log/$v2ray_name/ + [ ! -e "/var/log/$v2ray_name/error.log" ] && printf '%s' "" > /var/log/$v2ray_name/error.log + chown -R $v2ray_name:$v2ray_name /var/log/$v2ray_name/ + chown -R $v2ray_name:$v2ray_name /usr/local/share/$v2ray_name/ + + V2rayConfigUpdate + + ServiceControl restart $v2ray_name + + Println "$info $v2ray_name 升级完成\n" +} + +V2rayConfigUpdate() +{ + if [ ! -e "$V2_CONFIG" ] + then + Println "$error $v2ray_name 未安装...\n" + exit 1 + fi + + if ! outbounds=$($JQ_FILE '.outbounds' "$V2_CONFIG" 2> /dev/null) || [ "$outbounds" == "null" ] + then + if grep -q '"path": "' < "$V2_CONFIG" + then + while IFS= read -r line + do + if [[ $line == *"path"* ]] + then + path=${line#*: \"} + path=${path%\"*} + break + fi + done < "$V2_CONFIG" + fi + + printf -v update_date '%(%m-%d-%H:%M:%S)T' -1 + cp -f "$V2_CONFIG" "${V2_CONFIG}_$update_date" + while IFS= read -r line + do + if [[ $line == *"port"* ]] + then + port=${line#*: } + port=${port%,*} + elif [[ $line == *"id"* ]] + then + id=${line#*: \"} + id=${id%\"*} + break + fi + done < "$V2_CONFIG" + + $JQ_FILE -n --arg port "${port:-$(GetFreePort)}" --arg id "${id:-$($V2CTL_FILE uuid)}" --arg path "${path:-/$(RandStr)}" \ + --arg error "/var/log/$v2ray_name/error.log" \ + '{ + "log": { + "access": "none", + "error": $error, + "loglevel": "error" + }, + "inbounds": [ + { + "listen": "127.0.0.1", + "port": $port | tonumber, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": $id, + "level": 0, + "alterId": 64, + "email": "name@localhost" + } + ] + }, + "streamSettings": { + "network": "ws", + "wsSettings": { + "path": $path + } + }, + "tag": "nginx-1" + } + ], + "outbounds": [ + { + "protocol": "freedom", + "tag": "direct" + }, + { + "protocol": "blackhole", + "tag": "block" + } + ], + "policy": { + "levels": { + "0": { + "handshake": 4, + "connIdle": 300, + "uplinkOnly": 2, + "downlinkOnly": 5, + "statsUserUplink": false, + "statsUserDownlink": false, + "bufferSize": 512 + } + }, + "system": { + "statsInboundUplink": false, + "statsInboundDownlink": false, + "statsOutboundUplink": false, + "statsOutboundDownlink": false + } + } + }' > "$V2_CONFIG" + + Println "$info $v2ray_name 配置文件已更新\n" + fi +} diff --git a/utils/ffmpeg b/utils/ffmpeg index 809af84..bea7b59 100644 --- a/utils/ffmpeg +++ b/utils/ffmpeg @@ -4,9 +4,9 @@ FFmpegInstall() then FFMPEG_FILE="$FFMPEG_FILE_ROOT/ffmpeg" FFPROBE_FILE="$FFMPEG_FILE_ROOT/ffprobe" - elif [ "$FFMPEG_ROOT" != "$HOME" ] && FFMPEG_FILE_ROOT=$(find "$HOME"/ffmpeg-git-* -type d 2> /dev/null | head -1) + elif FFMPEG_FILE_ROOT=$(find "$IPTV_ROOT"/ffmpeg-git-* -type d 2> /dev/null | head -1) then - FFMPEG_ROOT="$HOME" + FFMPEG_ROOT="$IPTV_ROOT" FFMPEG_FILE="$FFMPEG_FILE_ROOT/ffmpeg" FFPROBE_FILE="$FFMPEG_FILE_ROOT/ffprobe" fi @@ -318,7 +318,8 @@ Cflags: -I\${includedir} cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DBUILD_SHARED_LIBS=OFF .. make $nproc make install - printf '%s' "prefix=$HOME/ffmpeg_build +cat > "$HOME"/ffmpeg_build/lib/pkgconfig/libxml-2.0.pc < "$HOME/ffmpeg_build/lib/pkgconfig/libxml-2.0.pc" +EOF # libpng (for openjpeg) cd ~/ffmpeg_sources @@ -741,7 +742,8 @@ Cflags: -I\${includedir} make install mkdir -p "$HOME/ffmpeg_build/include/rubberband/" cp -f ../rubberband/* "$HOME/ffmpeg_build/include/rubberband/" - printf '%s' "prefix=$HOME/ffmpeg_build +cat > "$HOME"/ffmpeg_build/lib/pkgconfig/rubberband.pc < "$HOME/ffmpeg_build/lib/pkgconfig/rubberband.pc" +EOF # libsrt cd ~/ffmpeg_sources diff --git a/utils/go b/utils/go index 30f3862..4aa29ee 100644 --- a/utils/go +++ b/utils/go @@ -1,5 +1,19 @@ GoInstall() { + if [[ ! "$PATH" =~ /usr/local/go/bin ]] + then + PATH="$PATH":/usr/local/go/bin + fi + + go_path=${GOPATH:-"$HOME"/go} + + if [[ ! "$PATH" =~ $go_path ]] + then + PATH="${PATH}:${go_path}/bin" + fi + + export PATH + if [[ -x $(command -v go) ]] then go_version_list=($(go version)) @@ -11,8 +25,8 @@ GoInstall() if [ "$dist" == "mac" ] then - DepInstall brew - brew install go + DepInstall go + return 0 fi ArchCheck @@ -24,7 +38,7 @@ GoInstall() if ! go_version=$(curl -s -Lm 20 https://go.dev/dl/?mode=json | $JQ_FILE -r '.[0].version') then Println "$error 无法连接 go.dev ?" - go_version=1.16.5 + go_version=1.22.2 fi if [ "$arch" == "i386" ] @@ -44,14 +58,9 @@ GoInstall() if ! curl -L https://golang.org/dl/$go_package -o ~/$go_package && ! curl -L https://gomirrors.org/dl/$go_package -o ~/$go_package then Println "$error 下载 golang 失败, 请稍后再试\n" - exit 1 + return 1 fi - rm -rf /usr/local/go && tar -C /usr/local -xzf ~/$go_package - - if [[ ! -x $(command -v go) ]] - then - export PATH="$PATH:/usr/local/go/bin" - echo "export PATH=\$PATH:/usr/local/go/bin" >> /etc/profile - fi + rm -rf /usr/local/go + tar -C /usr/local -xzf ~/$go_package } diff --git a/utils/htpasswd b/utils/htpasswd new file mode 100644 index 0000000..e8f0a84 --- /dev/null +++ b/utils/htpasswd @@ -0,0 +1,17 @@ +HtpasswdInstall() +{ + if [[ -x $(command -v htpasswd) ]] + then + return 0 + fi + + if [ "$dist" == "mac" ] + then + BrewInstall httpd + elif [ "$dist" == "rpm" ] + then + DepInstall httpd-tools + else + DepInstall apache2-utils + fi +} diff --git a/utils/i18n b/utils/i18n index 620c8de..9d2fe50 100644 --- a/utils/i18n +++ b/utils/i18n @@ -261,6 +261,11 @@ grep() ggrep "$@" } +base64() +{ + gbase64 "$@" +} + else TEXTDOMAINDIR=/usr/share/locale fi diff --git a/utils/imagemagick b/utils/imagemagick index ee979a9..4cc149d 100644 --- a/utils/imagemagick +++ b/utils/imagemagick @@ -1,21 +1,16 @@ ImageMagickInstall() { - Progress & - progress_pid=$! - trap ' - kill $progress_pid - wait $progress_pid 2> /dev/null - ' EXIT + if [[ -x $(command -v convert) ]] + then + return 0 + fi + rm -f "$IPTV_ROOT/magick" + if [ "$dist" == "rpm" ] then - yum -y install ImageMagick >/dev/null 2>&1 + DepInstall ImageMagick else - apt-get -y install imagemagick >/dev/null 2>&1 + DepInstall imagemagick fi - kill $progress_pid - wait $progress_pid 2> /dev/null || true - trap - EXIT - echo -n "...100%" - Println "\n`eval_gettext \"\\\$info magick 安装完成\"`\n" } diff --git a/utils/inquirer b/utils/inquirer index d74e1da..b3e0425 100644 --- a/utils/inquirer +++ b/utils/inquirer @@ -127,9 +127,9 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - if [ -n "${checkbox_pages_tip:-}" ] + if [ -n "${pages_tip:-}" ] then - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" fi tput cud $((current_index+1)) first_keystroke=false @@ -141,12 +141,12 @@ inquirer() tput cub "$(tput cols)" tput cuf $((prompt_width+3)) tput el - inquirer:print "$checkbox_pages_tip" + inquirer:print "$pages_tip" tput cud $((current_index+1)) } inquirer:on_checkbox_input_up() { - if [ "$checkbox_input_search" = true ] + if [ "$input_search" = true ] then tput cub "$(tput cols)" tput el @@ -160,29 +160,29 @@ inquirer() local i - for((i=0;i 选择, 确认)\"`${normal}\n\n\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n\n\n" fi inquirer:on_checkbox_input_up return fi - if [ "$checkbox_input_page" = true ] + if [ "$input_page" = true ] then - checkbox_input_page=false - if [ -n "${checkbox_input_page_num:-}" ] + input_page=false + if [ -n "${input_page_num:-}" ] then - if [ "$checkbox_input_page_num" -gt "$checkbox_pages_count" ] || [ "$checkbox_input_page_num" -eq $((checkbox_pages_index+1)) ] + if [ "$input_page_num" -gt "$pages_count" ] || [ "$input_page_num" -eq $((pages_index+1)) ] then - checkbox_input_page_num="" + input_page_num="" return fi - checkbox_pages_index=$((checkbox_input_page_num-1)) + pages_index=$((input_page_num-1)) - checkbox_pages_tip="${dim}$checkbox_pages_arrows $((checkbox_pages_index+1))/$checkbox_pages_count `gettext \"页\"`${normal}" + pages_tip="${dim}$pages_arrows $((pages_index+1))/$pages_count `gettext \"页\"`${normal}" - if [ "$checkbox_input_page_num" -eq "$checkbox_pages_count" ] + if [ "$input_page_num" -eq "$pages_count" ] then - checkbox_page_list_count=$((checkbox_list_count-checkbox_pages_index*checkbox_list_perpage)) + page_list_count=$((list_count-pages_index*list_perpage)) else - checkbox_page_list_count=$checkbox_list_perpage + page_list_count=$list_perpage fi inquirer:page_instructions tput cub "$(tput cols)" - tput cud $((checkbox_list_perpage-current_index+1)) + tput cud $((list_perpage-current_index+1)) - for((i=0;i<=checkbox_list_perpage;i++)); + for((i=0;i<=list_perpage;i++)); do tput el tput cuu1 @@ -542,71 +543,71 @@ inquirer() tput el - if [ "$current_index" -gt "$checkbox_page_list_count" ] + if [ "$current_index" -gt "$page_list_count" ] then - current_index=$checkbox_page_list_count + current_index=$page_list_count fi - checkbox_page_list=() + page_list=() checkbox_page_selected=() checkbox_page_select_all=true - for((i=0;i 选择, 确认)\"`${normal}\n" + inquirer:print "${green}?${normal} ${bold}${bg_black}${white}${prompt} ${pages_tip:-}${dim}`gettext \"(按 选择, 确认)\"`${normal}\n" for i in "${!checkbox_list[@]}" do @@ -847,7 +848,7 @@ inquirer() else inquirer:print "${cyan}${arrow}${normal}${unchecked} ${checkbox_list[i]}\n" fi - elif [ "$checkbox_pages_count" -gt 1 ] && [ "$i" = "$checkbox_list_perpage" ] + elif [ "$pages_count" -gt 1 ] && [ "$i" = "$list_perpage" ] then break else @@ -858,11 +859,11 @@ inquirer() inquirer:print " ${unchecked} ${checkbox_list[i]}\n" fi fi - ((checkbox_page_list_count++)) - checkbox_page_list+=("${checkbox_list[i]}") + page_list_count=$((page_list_count+1)) + page_list+=("${checkbox_list[i]}") done - for((i=0;i /etc/yum.repos.d/mongodb-org-4.4.repo < /etc/yum.repos.d/mongodb-org-4.4.repo +EOF yum install -y mongodb-org >/dev/null 2>&1 else @@ -66,7 +66,7 @@ gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc if [[ $(ps --no-headers -o comm 1) == "systemd" ]] then sed -i "s/LimitNOFILE=.*/LimitNOFILE=$file_max/" /lib/systemd/system/mongod.service - sed -i '/TasksAccounting=/a RestartSec=5\nStartLimitIntervalSec=0\nRestart=on-failure' /lib/systemd/system/mongod.service + sed -i '/TasksAccounting=/a StartLimitInterval=60s\nStartLimitBurst=5\nRestartSec=5\nRestart=on-failure' /lib/systemd/system/mongod.service systemctl daemon-reload sed -i "s/destination: file/destination: syslog/" /etc/mongod.conf sed -i "s/ logAppend: true/ #logAppend: true/" /etc/mongod.conf diff --git a/utils/nodejs b/utils/nodejs index 4647487..ef17178 100644 --- a/utils/nodejs +++ b/utils/nodejs @@ -29,14 +29,14 @@ NodejsInstall() yum -y install gcc-c++ make >/dev/null 2>&1 # yum groupinstall 'Development Tools' - if bash <(curl -sL https://rpm.nodesource.com/setup_14.x) > /dev/null + if curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - >/dev/null then - yum -y install nodejs >/dev/null 2>&1 + sudo yum install -y nsolid >/dev/null 2>&1 fi else - if bash <(curl -sL https://deb.nodesource.com/setup_14.x) > /dev/null + if curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - >/dev/null then - apt-get install -y nodejs >/dev/null 2>&1 + sudo apt-get install -y nodejs >/dev/null 2>&1 fi fi diff --git a/utils/openssl b/utils/openssl index 575d3e5..3dba914 100644 --- a/utils/openssl +++ b/utils/openssl @@ -5,24 +5,13 @@ OpensslInstall() return 0 fi - echo - ExitOnList y "`gettext \"是否安装 openssl\"`" - - Progress & - progress_pid=$! - trap ' - kill $progress_pid - wait $progress_pid 2> /dev/null - ' EXIT + DepInstall openssl if [ "$dist" == "rpm" ] then - yum -y install openssl openssl-devel >/dev/null 2>&1 - else - apt-get -y install openssl libssl-dev >/dev/null 2>&1 + DepInstall openssl-devel + elif [ "$dist" != "mac" ] + then + DepInstall libssl-dev fi - kill $progress_pid - wait $progress_pid 2> /dev/null || true - trap - EXIT - echo -n "...100%" && Println "`eval_gettext \"\\\$info openssl 安装完成\"`" } diff --git a/utils/python b/utils/python index 5245585..00d8f41 100644 --- a/utils/python +++ b/utils/python @@ -26,9 +26,9 @@ PythonInstall() yum install -y gcc openssl-devel bzip2-devel libffi-devel >/dev/null 2>&1 echo -n "...50%..." cd ~ - wget --timeout=10 --tries=3 --no-check-certificate https://www.python.org/ftp/python/3.8.9/Python-3.8.9.tgz -qO Python-3.8.9.tgz - tar xzf Python-3.8.9.tgz - cd Python-3.8.9 + wget --timeout=10 --tries=3 --no-check-certificate https://www.python.org/ftp/python/3.12.2/Python-3.12.2.tgz -qO Python-3.12.2.tgz + tar xzf Python-3.12.2.tgz + cd Python-3.12.2 ./configure >/dev/null 2>&1 make >/dev/null 2>&1 make install >/dev/null 2>&1 diff --git a/utils/shfile b/utils/shfile index 30aa976..67cc323 100644 --- a/utils/shfile +++ b/utils/shfile @@ -107,6 +107,8 @@ ShFileCheck() [ ! -e "$PVE_FILE" ] && ln -s "$SH_FILE" "$PVE_FILE" [ ! -e "$ALIST_FILE" ] && ln -s "$SH_FILE" "$ALIST_FILE" [ ! -e "$LIANHUANHUA_FILE" ] && ln -s "$SH_FILE" "$LIANHUANHUA_FILE" + [ ! -e "$RCLONE_FILE" ] && ln -s "$SH_FILE" "$RCLONE_FILE" + [ ! -e "$CALIBRE_FILE" ] && ln -s "$SH_FILE" "$CALIBRE_FILE" return 0 } diff --git a/utils/system b/utils/system index 766d70a..a9e5a28 100644 --- a/utils/system +++ b/utils/system @@ -48,10 +48,10 @@ ArchCheck() if grep -Eqi "x86_64|amd64" <<< "$arch" then arch="x86_64" - elif grep -Eqi "i386|i686" <<< "$arch" + elif grep -Eqi "i386|i686|x86" <<< "$arch" then arch="i386" - elif grep -Eqi "aarch64|armv8" <<< "$arch" + elif grep -Eqi "aarch64|armv8|arm64" <<< "$arch" then arch="arm64" elif grep -qi "armv7" <<< "$arch" @@ -87,23 +87,23 @@ DebFixSources() if grep -q "jessie" <<< "$deb_list" then - printf '%s' " +cat > /etc/apt/sources.list < "/etc/apt/sources.list" +EOF apt-get clean >/dev/null 2>&1 elif grep -q "wheezy" <<< "$deb_list" then - printf '%s' " +cat > /etc/apt/sources.list < "/etc/apt/sources.list" +EOF apt-get clean >/dev/null 2>&1 fi @@ -443,7 +443,7 @@ ResourceLimit() then if [ ! -e ~/.bash_profile ] || ! grep -q ulimit < ~/.bash_profile then -cat >> ~/.bash_profile << EOF +cat >> ~/.bash_profile <> ~/.profile << EOF +cat >> ~/.profile < "$HOME"/.vimrc < ~/.vimrc +EOF DepInstall git Println "$info vimrc 设置完成, 请在 vim 下执行 PlugInstall\n" else