Files
Linux/1.sh
T

309 lines
9.8 KiB
Bash

#!/usr/bin/env bash
#
# ...
#
# 使用方法:
# URL="https://git.1-h.cc/Scripts/Linux/raw/branch/2026/1.sh"; curl -fsSL "$URL" | bash
# URL="https://git.1-h.cc/Scripts/Linux/raw/branch/2026/1.sh"; wget -q -O - "$URL" | bash
set -e # 遇到错误即退出
trap 'echo "Error on line $LINENO"' ERR
print_red() { echo -e "\033[31m\033[01m$1$2\033[0m"; }
print_green() { echo -e "\033[32m\033[01m$1$2\033[0m"; }
print_yellow() { echo -e "\033[33m\033[01m$1$2\033[0m"; }
SCRIPT_BASE_URL="https://git.1-h.cc/Scripts/Linux/raw/branch/2026"
SCRIPT_DIR=""
if [ -n "${BASH_SOURCE[0]:-}" ]; then
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || true)
fi
load_shared_script() {
local relative_path="$1"
local local_path remote_url
local_path="$SCRIPT_DIR/$relative_path"
remote_url="$SCRIPT_BASE_URL/$relative_path"
if [ -n "$SCRIPT_DIR" ] && [ -f "$local_path" ]; then
source "$local_path"
elif command -v curl >/dev/null 2>&1; then
source <(curl -fsSL "$remote_url")
elif command -v wget >/dev/null 2>&1; then
source <(wget -q -O - "$remote_url")
else
print_red "未找到 curl 或 wget,无法加载 $relative_path"
exit 1
fi
}
if [ "$EUID" -ne 0 ]; then
print_red "请使用 sudo 运行此脚本"
exit 1
fi
# 设置 bash 为默认 shell
print_green "###################"
print_green "##### shell ######"
print_green "###################"
if [ -f /etc/debian_version ]; then
chsh -s $(which bash)
print_green "已将 bash 设置为默认 shell"
elif [ -f /etc/alpine-release ]; then
apk add --no-cache shadow
chsh -s $(which bash) root
# sed -i 's|^\(root:.*\):[^:]*$|\1:/bin/bash|' /etc/passwd
# sed -i 's|^\(root:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*\):[^:]*$|\1:/bin/bash|' /etc/passwd
print_yellow "已将 bash 设置为默认 shell"
apk del shadow
fi
# 先检查是 Debian 还是 Alpine
if [ -f /etc/debian_version ]; then
SYSTEM_TYPE="debian"
echo "检测到 Debian 系统"
elif [ -f /etc/alpine-release ]; then
SYSTEM_TYPE="alpine"
echo "检测到 Alpine 系统"
else
echo "不支持的系统类型"
exit 1
fi
# load_shared_script "zram/install.sh"
sysctl_config() {
print_green "###################"
print_green "##### sysctl ######"
print_green "###################"
# 确定 sysctl 配置文件路径
SYSCTL_CONF="/etc/sysctl.conf"
SYSCTL_CLEANUP_FILES=("/etc/sysctl.conf" "/etc/sysctl.d/99-sysctl.conf" "/etc/sysctl.d/999-custom.conf")
if [ "$SYSTEM_TYPE" = "debian" ]; then
DEBIAN_VERSION=$(grep -oP 'VERSION_ID="\K[^"]+' /etc/os-release 2>/dev/null || cat /etc/debian_version 2>/dev/null | cut -d. -f1)
if [ -z "$DEBIAN_VERSION" ]; then
echo "无法确定 Debian 版本,使用默认配置文件"
elif (( DEBIAN_VERSION >= 13 )); then
SYSCTL_CONF="/etc/sysctl.d/999-custom.conf"
echo "检测到 Debian $DEBIAN_VERSION,使用 $SYSCTL_CONF"
else
echo "检测到 Debian $DEBIAN_VERSION,使用 $SYSCTL_CONF"
fi
fi
SYSCTL_SETTINGS=(
"vm.swappiness=10"
"vm.overcommit_memory=1"
"net.core.rmem_max=16777216"
"net.core.wmem_max=16777216"
"net.core.default_qdisc=fq_codel"
# "net.core.default_qdisc=fq"
"net.ipv4.tcp_congestion_control=bbr"
"net.ipv4.tcp_slow_start_after_idle=0"
"net.ipv4.tcp_notsent_lowat=16384"
# "net.ipv4.tcp_notsent_lowat=131072"
)
# # 确保配置文件目录存在
mkdir -p "$(dirname "$SYSCTL_CONF")"
touch "$SYSCTL_CONF"
for SETTING in "${SYSCTL_SETTINGS[@]}"; do # 遍历数组
KEY=$(echo "$SETTING" | cut -d '=' -f 1) # 截取=左边的字符串
KEY_PATH="/proc/sys/${KEY//./\/}"
if [ ! -e "$KEY_PATH" ]; then
print_yellow "跳过不支持的 sysctl: $KEY"
continue
fi
KEY_REGEX=${KEY//./\\.}
for CLEANUP_FILE in "${SYSCTL_CLEANUP_FILES[@]}"; do
if [ -f "$CLEANUP_FILE" ]; then
sed -i "/^[[:space:]]*${KEY_REGEX}[[:space:]]*=.*/d" "$CLEANUP_FILE"
fi
done
echo "$SETTING" >>"$SYSCTL_CONF" # 追加新的配置
# echo "已添加系统配置: $SETTING" # 输出提示信息
done # 循环结束
if [ "$SYSTEM_TYPE" = "alpine" ]; then
sysctl -p
else
sysctl --system
fi
}
detect_cn_network() {
local check_urls=(
"https://developers.cloudflare.com/cdn-cgi/trace"
"https://ipinfo.io"
)
for check_url in "${check_urls[@]}"; do
local response
response=$(curl -fsSL "$check_url" || true)
if echo "$response" | grep -q "CN"; then
echo "检测到中国网络环境 (来源: $check_url)"
return 0
fi
done
return 1
}
check_container_runtime() {
if [ -x "$(command -v podman)" ]; then
echo "检测到 Podman 已安装,跳过 Docker 相关配置"
return 0
fi
return 1
}
install_docker() {
print_green "###################"
print_green "##### docker ######"
print_green "###################"
if check_container_runtime; then
return 0
fi
if [ -x "$(command -v docker)" ]; then
echo "Docker 已安装"
else
echo "Docker 未安装,正在安装中..."
if [ "$SYSTEM_TYPE" = "debian" ]; then
echo "在 Debian 系统上安装 Docker..."
if detect_cn_network; then
echo "使用 cloudlayer.icu 安装脚本"
curl -fsSL https://cloudlayer.icu/docker-install.sh | sh
else
echo "使用官方 Docker 安装脚本"
curl -fsSL https://get.docker.com/ | sh
fi
elif [ "$SYSTEM_TYPE" = "alpine" ]; then
echo "在 Alpine 系统上安装 Docker..."
apk add --no-cache docker
apk add --no-cache docker-cli-compose
rc-update add docker default
rc-service docker start
else
print_red "不支持的系统类型"
exit 1
fi
fi
# docker network create --attachable h-common || true
}
modify_authorized_keys() {
print_green "###################"
print_green "# authorized_keys #"
print_green "###################"
echo "正在修改 authorized_keys"
mkdir -p /root/.ssh/
AUTHORIZED_KEY="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDi6fLhEYp2mmUUBOB/6CA0iQYcwhAUVBwpbJJhK0fZmvmtrCrfkDvFtqw4WH0D/DgRtJNyoDfrQ2gm67FtFzu2ZfH0PtIEI6JWrh432qjQnAT5cuKbN3ghrjTHf08vjh0axxilSFtCXf5Gyv+ZnABil7GZAhJB5K/yBUMr6OD5fp4tvjAYe0t6ZIQb8vgd0dCXDGA3Rak1B7W24vDA1Col+Qvx5I7pfqiebkof7BbkfBYX5KZ/ArK0n1RV7wBjf6g/XkwRPvpCR5rz7s+UnMr2FFYqfQ1wkpKjo74KzAahFyy7UicM3e7OKfZvd8EmWBysIdKCcl9s/H9Z4Q/TDZsmnr68KweCvpqFVHfKS9CZ/7w/7zQhrXDhnysqt6nmp/moQLMax6b62++4X6E0gyopc2nlMT+QjIwRPl+DPC2UicWniOSAuSvpPxt8YXF4Zbpsg0efMQvHDrjQF6Ws9UIKVQeTBqij+TJ3w5aUbLEjPhrP5ia7Dtn7u/3IsosxW00= yanhao@yanhaodeMacBook-Pro.local"
echo $AUTHORIZED_KEY >/root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
# wget -q -O /tmp/sshd_config https://script.yanhao.ren/downloads/sshd_config
# mv /tmp/sshd_config /etc/ssh/sshd_config
# service sshd restart
}
bash_aliases() {
print_green "###################"
print_green "## bash_aliases ###"
print_green "###################"
rm -f /root/.bash_aliases
# 确保 .bashrc 包含别名加载代码
touch /root/.bash_aliases
grep -q "/root/.bash_aliases" /root/.bashrc || echo '
if [ -f /root/.bash_aliases ]; then
. ~/.bash_aliases
fi' >>/root/.bashrc
cat <<'EOF' >/root/.bash_aliases
alias maddy='docker exec -it maddy maddy'
alias l='ls -l'
alias ll='ls -alF'
alias telnet='docker run --quiet --rm --network host --entrypoint telnet busybox:latest'
alias dstats='docker stats --no-stream'
alias dps='docker ps --size --format "table {{.Names}}\t{{.Status}}\t{{.Size}}"'
alias dpull='docker compose pull'
alias ddown='docker compose down'
alias dcreate='docker compose create'
alias dup='docker compose up --remove-orphans'
alias iperf3='docker run --rm -it --network host networkstatic/iperf3'
EOF
# 如果是 Alpine 系统,创建一个软链接。
# /etc/profile.d/00-bashrc.sh
# . /etc/bash/bashrc
# . /etc/bash/*.sh
if [ "$SYSTEM_TYPE" = "alpine" ]; then
if [ ! -e "/etc/bash/root-bashrc.sh" ]; then
ln -s /root/.bashrc /etc/bash/root-bashrc.sh
echo "已创建软链接: /etc/bash/root-bashrc.sh"
else
echo "软链接已存在: /etc/bash/root-bashrc.sh"
fi
fi
print_yellow "别名配置已完成"
print_yellow "请执行以下命令使配置生效:"
print_yellow "source /root/.bashrc"
}
start_watchtower() {
# [Goodbye containrrr/watchtower!](https://github.com/containrrr/watchtower/discussions/2135)
# https://github.com/nicholas-fedor/watchtower
print_green "###################"
print_green "#### watchtower ###"
print_green "###################"
if check_container_runtime; then
return 0
fi
WATCHTOWER_RUN_ONCE=false # 是否只运行一次
WATCHTOWER_NAME="" # 如果不设置 container_name,则会监控所有容器
WATCHTOWER_DOCKER_ARGS=()
WATCHTOWER_ARGS=()
WATCHTOWER_ARGS+=(--cleanup)
# WATCHTOWER_ARGS+=(--remove-volumes)
WATCHTOWER_ARGS+=(--rolling-restart)
WATCHTOWER_ARGS+=(--api-version=1.44)
if [ "$WATCHTOWER_RUN_ONCE" = true ]; then
WATCHTOWER_ARGS+=(--run-once)
WATCHTOWER_DOCKER_ARGS+=(--rm)
else
WATCHTOWER_ARGS+=(--label-enable) # 仅监控并更新标签为 com.centurylinklabs.watchtower.enable 设置为 true 的容器。
WATCHTOWER_ARGS+=(--schedule "0 0 3 * * *") # 每天凌晨 3 点执行
WATCHTOWER_DOCKER_ARGS+=(-d)
WATCHTOWER_DOCKER_ARGS+=(--restart unless-stopped)
WATCHTOWER_DOCKER_ARGS+=(--name watchtower)
fi
if [ -f ~/.docker/config.json ]; then # 如果 ~/.docker/config.json 存在
WATCHTOWER_DOCKER_ARGS+=(-v ~/.docker/config.json:/config.json)
fi
docker rm -f watchtower
docker run "${WATCHTOWER_DOCKER_ARGS[@]}" \
-e WATCHTOWER_NO_STARTUP_MESSAGE \
-e TZ=Asia/Shanghai \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower "${WATCHTOWER_ARGS[@]}" $WATCHTOWER_NAME
}
modify_authorized_keys
bash_aliases
install_docker
start_watchtower
install_zram
sysctl_config
# source <(curl -fsSL scripts.oo1.dev/nezha-v1.sh)