feat: add script catalog and -h help for all dotfile scripts
Introduce ff script -h with auto descriptions, shared help.sh, and usage flags across script/*.sh. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+15
-13
@@ -65,22 +65,24 @@ complete -c ff -n "__fish_seen_subcommand_from ssh copy; and test (count (comman
|
|||||||
|
|
||||||
# script 子命令的补全 - 动态列出 script 目录下的脚本
|
# script 子命令的补全 - 动态列出 script 目录下的脚本
|
||||||
function __ff_list_scripts
|
function __ff_list_scripts
|
||||||
set -l script_dir ~/.dotfile/script
|
if not functions -q script-list-names
|
||||||
if test -d $script_dir
|
source ~/.dotfile/fish/functions/script-catalog.fish
|
||||||
# 列出 .sh 文件
|
|
||||||
for script in $script_dir/*.sh
|
|
||||||
if test -f $script
|
|
||||||
basename $script | string replace -r '\.sh$' ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# 列出 .py 文件
|
|
||||||
for script in $script_dir/*.py
|
|
||||||
if test -f $script
|
|
||||||
basename $script | string replace -r '\.py$' ''
|
|
||||||
end
|
end
|
||||||
|
script-list-names
|
||||||
|
end
|
||||||
|
|
||||||
|
function __ff_complete_scripts
|
||||||
|
if not functions -q script-extract-description
|
||||||
|
source ~/.dotfile/fish/functions/script-catalog.fish
|
||||||
end
|
end
|
||||||
|
for name in (script-list-names)
|
||||||
|
set -l path (script-resolve-path $name)
|
||||||
|
set -l desc (script-extract-description $path)
|
||||||
|
printf "%s\t%s\n" $name $desc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -c ff -n "__fish_seen_subcommand_from script" -a '(__ff_list_scripts)' -d "Script name"
|
complete -c ff -n "__fish_seen_subcommand_from script; and test (count (commandline -opc)) -eq 2" -s h -l help -d "List all scripts and descriptions"
|
||||||
|
complete -c ff -n "__fish_seen_subcommand_from script; and test (count (commandline -opc)) -eq 2" -a help -d "List all scripts and descriptions"
|
||||||
|
complete -c ff -n "__fish_seen_subcommand_from script; and not __fish_seen_subcommand_from help -h --help (__ff_list_scripts)" -a '(__ff_complete_scripts)' -d "Script name"
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,42 @@
|
|||||||
# Execute script from script directory
|
# Execute script from script directory
|
||||||
function execute-script
|
function execute-script
|
||||||
# 执行 script 目录下的脚本
|
if not functions -q script-show-catalog
|
||||||
|
source ~/.dotfile/fish/functions/script-catalog.fish
|
||||||
|
end
|
||||||
|
|
||||||
set -l dotfile_dir ~/.dotfile
|
set -l dotfile_dir ~/.dotfile
|
||||||
set -l script_dir $dotfile_dir/script
|
set -l script_dir $dotfile_dir/script
|
||||||
set -l script_name $argv[1]
|
set -l script_name $argv[1]
|
||||||
|
|
||||||
|
# ff script -h / --help / help
|
||||||
|
if test -z "$script_name"; or contains -- $script_name -h --help help
|
||||||
|
if test -z "$script_name"; or test (count $argv) -eq 1
|
||||||
|
script-show-catalog
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if test -z "$script_name"
|
if test -z "$script_name"
|
||||||
echo "Error: No script name specified"
|
script-show-catalog
|
||||||
echo "Usage: execute-script <script_name> [args...]"
|
|
||||||
echo ""
|
|
||||||
echo "Available scripts:"
|
|
||||||
if test -d $script_dir
|
|
||||||
for script in $script_dir/*.sh $script_dir/*.py
|
|
||||||
if test -f $script
|
|
||||||
set -l basename (basename $script)
|
|
||||||
echo " $basename"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# 尝试不同的扩展名
|
set -l script_path (script-resolve-path $script_name 2>/dev/null; or echo "")
|
||||||
set -l script_path ""
|
|
||||||
for ext in sh py
|
|
||||||
set -l test_path $script_dir/$script_name.$ext
|
|
||||||
if test -f $test_path
|
|
||||||
set script_path $test_path
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# 如果没找到,尝试直接使用提供的名称
|
if test -n "$script_path" -a -f "$script_path"
|
||||||
if test -z "$script_path"
|
|
||||||
set script_path $script_dir/$script_name
|
|
||||||
end
|
|
||||||
|
|
||||||
if test -f $script_path
|
|
||||||
echo "Running: $script_path"
|
echo "Running: $script_path"
|
||||||
if test -x $script_path
|
if test -x $script_path
|
||||||
$script_path $argv[2..-1]
|
$script_path $argv[2..-1]
|
||||||
else
|
else if string match -q "*.py" $script_path
|
||||||
# 根据文件类型选择解释器
|
|
||||||
if string match -q "*.py" $script_path
|
|
||||||
python3 $script_path $argv[2..-1]
|
python3 $script_path $argv[2..-1]
|
||||||
else
|
else
|
||||||
bash $script_path $argv[2..-1]
|
bash $script_path $argv[2..-1]
|
||||||
end
|
end
|
||||||
|
return $status
|
||||||
end
|
end
|
||||||
else
|
|
||||||
echo "Error: Script not found: $script_name"
|
|
||||||
echo "Available scripts:"
|
|
||||||
if test -d $script_dir
|
|
||||||
for script in $script_dir/*.sh $script_dir/*.py
|
|
||||||
if test -f $script
|
|
||||||
set -l basename (basename $script)
|
|
||||||
echo " $basename"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
echo "Error: Script not found: $script_name"
|
||||||
|
echo ""
|
||||||
|
script-show-catalog
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
# 列举 ~/.dotfile/script 下脚本及从文件头注释提取的简短说明
|
||||||
|
|
||||||
|
function script-extract-description --argument filepath
|
||||||
|
if not test -f "$filepath"
|
||||||
|
echo "(无描述)"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l past_shebang 0
|
||||||
|
set -l candidates
|
||||||
|
for line in (cat "$filepath")
|
||||||
|
if string match -qr '^#!/' -- $line
|
||||||
|
set past_shebang 1
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if test $past_shebang -eq 0
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
set line (string trim $line)
|
||||||
|
if test -z "$line"
|
||||||
|
if test (count $candidates) -gt 0
|
||||||
|
break
|
||||||
|
end
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if not string match -qr '^#' -- $line
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
set line (string replace -r '^#\s*' '' $line)
|
||||||
|
if string match -qr '^---' -- $line
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if string match -qr '^(用法|Usage|示例|Example)' -- $line
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if string match -qr '^\./' -- $line
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
if string match -qr '^https?://' -- $line
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
# 行内 “# 用法” 类注释
|
||||||
|
if string match -qr '#\s*(用法|Usage)' -- $line
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
set candidates $candidates $line
|
||||||
|
if test (count $candidates) -ge 8
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if test (count $candidates) -eq 0
|
||||||
|
echo "(无描述)"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for c in $candidates
|
||||||
|
if string match -qr '(脚本|安装|初始化|清理|扫描|切换|配置|用于|镜像|凭据|用户组|免密|Install|Init|Clean|Toggle)' -- $c
|
||||||
|
echo $c
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for c in $candidates
|
||||||
|
if test (string length $c) -ge 10
|
||||||
|
echo $c
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
echo $candidates[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function script-list-names
|
||||||
|
set -l script_dir ~/.dotfile/script
|
||||||
|
set -l names
|
||||||
|
if not test -d $script_dir
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for script in $script_dir/*.sh $script_dir/*.py
|
||||||
|
if test -f $script
|
||||||
|
set -l name (basename $script)
|
||||||
|
set name (string replace -r '\.(sh|py)$' '' $name)
|
||||||
|
set names $names $name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
string join \n $names | sort
|
||||||
|
end
|
||||||
|
|
||||||
|
function script-resolve-path --argument name
|
||||||
|
set -l script_dir ~/.dotfile/script
|
||||||
|
for ext in sh py
|
||||||
|
set -l path "$script_dir/$name.$ext"
|
||||||
|
if test -f $path
|
||||||
|
echo $path
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if test -f "$script_dir/$name"
|
||||||
|
echo "$script_dir/$name"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function script-show-catalog
|
||||||
|
set -l script_dir ~/.dotfile/script
|
||||||
|
echo "Usage: ff script <name> [args...]"
|
||||||
|
echo ""
|
||||||
|
echo "Scripts in $script_dir:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for name in (script-list-names)
|
||||||
|
set -l path (script-resolve-path $name)
|
||||||
|
set -l desc (script-extract-description $path)
|
||||||
|
printf " %-22s %s\n" $name $desc
|
||||||
|
end
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "提示: ff script <name> -h 查看单个脚本内的详细帮助"
|
||||||
|
end
|
||||||
@@ -1 +1,28 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 清理 Homebrew 缓存与无用文件
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: brew-clean
|
||||||
|
|
||||||
|
执行 Homebrew 清理(brew cleanup),删除旧版本与缓存。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if ! command -v brew &>/dev/null; then
|
||||||
|
echo "错误: 未找到 brew,请先安装 Homebrew" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
brew cleanup
|
||||||
|
|||||||
@@ -1,3 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 使用国内镜像安装 Homebrew
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: brew-install
|
||||||
|
|
||||||
|
通过中科大镜像安装 Homebrew(设置 HOMEBREW_* 镜像环境变量后执行官方安装脚本)。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.ustc.edu.cn/brew.git"
|
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.ustc.edu.cn/brew.git"
|
||||||
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.ustc.edu.cn/homebrew-core.git"
|
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.ustc.edu.cn/homebrew-core.git"
|
||||||
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.ustc.edu.cn/homebrew-bottles"
|
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.ustc.edu.cn/homebrew-bottles"
|
||||||
|
|||||||
+27
-1
@@ -1,5 +1,31 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Copy stdin to the system clipboard (macOS / Linux X11 / Linux Wayland).
|
# 将标准输入复制到系统剪贴板(macOS / Linux X11 / Wayland)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: clip-copy
|
||||||
|
|
||||||
|
从 stdin 读取内容并写入系统剪贴板。
|
||||||
|
|
||||||
|
支持:
|
||||||
|
macOS: pbcopy
|
||||||
|
Wayland: wl-copy
|
||||||
|
X11: xclip / xsel
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
示例:
|
||||||
|
echo hello | clip-copy
|
||||||
|
cat file.txt | clip-copy
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# 供 script/*.sh source:统一处理 -h / --help
|
||||||
|
# 调用方需先定义 usage() 函数
|
||||||
|
|
||||||
|
dotfile_help_requested() {
|
||||||
|
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_show_help() {
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
+25
-9
@@ -1,21 +1,40 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 执行命令并在失败时通过飞书 Webhook 发送通知
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: croncheck <command> [args...]
|
||||||
|
|
||||||
|
执行给定命令;若退出码非 0,向配置的飞书 Webhook 发送失败通知。
|
||||||
|
最终以原命令的退出码退出。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
示例:
|
||||||
|
croncheck /path/to/backup.sh
|
||||||
|
croncheck docker compose up -d
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
# 检查参数数量
|
|
||||||
if [ "$#" -lt 1 ]; then
|
if [ "$#" -lt 1 ]; then
|
||||||
echo "Usage: $0 <command> [command_args...]"
|
echo "错误: 缺少要执行的命令" >&2
|
||||||
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 获取 webhook URL
|
|
||||||
WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/808eafd8-a79f-4af0-b730-8442cf15933b"
|
WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/808eafd8-a79f-4af0-b730-8442cf15933b"
|
||||||
|
|
||||||
# 执行命令并捕获输出
|
|
||||||
OUTPUT=$("$@" 2>&1)
|
OUTPUT=$("$@" 2>&1)
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
|
|
||||||
# 如果命令失败,发送 webhook 通知
|
|
||||||
if [ $EXIT_CODE -ne 0 ]; then
|
if [ $EXIT_CODE -ne 0 ]; then
|
||||||
# 准备 JSON 数据
|
|
||||||
JSON_DATA=$(cat <<EOF
|
JSON_DATA=$(cat <<EOF
|
||||||
{
|
{
|
||||||
"msg_type": "text",
|
"msg_type": "text",
|
||||||
@@ -25,10 +44,7 @@ if [ $EXIT_CODE -ne 0 ]; then
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
# 发送 webhook
|
|
||||||
curl -s -X POST -H "Content-Type: application/json" -d "$JSON_DATA" "$WEBHOOK_URL"
|
curl -s -X POST -H "Content-Type: application/json" -d "$JSON_DATA" "$WEBHOOK_URL"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 退出,使用原命令的退出码
|
|
||||||
exit $EXIT_CODE
|
exit $EXIT_CODE
|
||||||
|
|
||||||
|
|||||||
+23
-2
@@ -1,15 +1,36 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 将 Cursor 用户配置链接到 dotfile(macOS)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: cursor-init
|
||||||
|
|
||||||
|
链接 ~/.dotfile/cursor/config/ 下的 settings.json、keybindings.json
|
||||||
|
到 Cursor 用户目录(macOS)。
|
||||||
|
|
||||||
|
已有文件会备份为 *.bak。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
echo 'Cursor config init'
|
echo 'Cursor config init'
|
||||||
|
|
||||||
# init settings.json
|
|
||||||
src="$HOME/Library/Application Support/Cursor/User/settings.json"
|
src="$HOME/Library/Application Support/Cursor/User/settings.json"
|
||||||
if [ -f "$src" ]; then
|
if [ -f "$src" ]; then
|
||||||
mv "$src" "$src.bak"
|
mv "$src" "$src.bak"
|
||||||
fi
|
fi
|
||||||
ln -s "$HOME/.dotfile/cursor/config/settings.json" "$src"
|
ln -s "$HOME/.dotfile/cursor/config/settings.json" "$src"
|
||||||
|
|
||||||
# init keybindings.json
|
|
||||||
src="$HOME/Library/Application Support/Cursor/User/keybindings.json"
|
src="$HOME/Library/Application Support/Cursor/User/keybindings.json"
|
||||||
if [ -f "$src" ]; then
|
if [ -f "$src" ]; then
|
||||||
mv "$src" "$src.bak"
|
mv "$src" "$src.bak"
|
||||||
|
|||||||
+19
-1
@@ -1,8 +1,26 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Debian 国内镜像源更换脚本
|
# Debian 国内镜像源更换脚本(交互式选择镜像)
|
||||||
# 支持 Debian 9/10/11/12/13 (stretch/buster/bullseye/bookworm/trixie)
|
# 支持 Debian 9/10/11/12/13 (stretch/buster/bullseye/bookworm/trixie)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: sudo debian-init
|
||||||
|
|
||||||
|
交互式将 Debian apt 源更换为国内镜像(需 root)。
|
||||||
|
自动检测版本代号,备份原 sources.list。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# 颜色定义
|
# 颜色定义
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
# Debian 一键更换清华镜像源脚本 (DEB822 格式)
|
# Debian 一键更换清华镜像源脚本 (DEB822 格式)
|
||||||
# 支持 Debian 12 (bookworm)、13 (trixie)、14 (forky) 及后续版本
|
# 支持 Debian 12 (bookworm)、13 (trixie)、14 (forky) 及后续版本
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: sudo debian-tuna
|
||||||
|
|
||||||
|
将 Debian apt 源一键替换为清华 DEB822 格式源(需 root)。
|
||||||
|
会处理 /etc/apt/sources.list.d/debian.sources 与旧版 sources.list。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# 颜色定义
|
# 颜色定义
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 查询目录大小(du 封装,支持排序与 Top N)
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
|||||||
+21
-2
@@ -1,7 +1,26 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 清理 macOS / Linux 系统 DNS 缓存
|
||||||
|
|
||||||
# 用法:
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
# ./dns-clean.sh # 清理 macOS / Linux 系统 DNS 缓存
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: dns-clean
|
||||||
|
|
||||||
|
按当前操作系统清理 DNS 缓存:
|
||||||
|
macOS: dscacheutil + mDNSResponder
|
||||||
|
Linux: systemd-resolved / nscd / dnsmasq / unbound(自动检测)
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
说明: 非 root 时会自动使用 sudo。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 清理 Docker 未使用的镜像、容器与缓存(docker system prune -a)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: docker-clean
|
||||||
|
|
||||||
|
执行 docker system prune -a,删除未使用的镜像、容器、网络等。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
警告: 会删除未使用的镜像,请确认无重要 dangling 资源。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
docker system prune -a
|
docker system prune -a
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# 将用户加入 docker 组(免 sudo 使用 docker)
|
# 将用户加入 docker 组(免 sudo 使用 docker)
|
||||||
# 用法: sudo docker-group <user>
|
|
||||||
# 示例: sudo docker-group xuser
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -17,12 +19,14 @@ usage() {
|
|||||||
说明:
|
说明:
|
||||||
- 用户需重新登录或 newgrp docker 后生效
|
- 用户需重新登录或 newgrp docker 后生效
|
||||||
- 安装 Docker 时 docker-install.sh 只会把当时的 $USER 加入组
|
- 安装 Docker 时 docker-install.sh 只会把当时的 $USER 加入组
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]] && usage
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
[[ $# -eq 1 ]] || usage
|
[[ $# -eq 1 ]] || { usage; exit 1; }
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "错误: 请使用 sudo 运行,例如: sudo $0 $1"
|
echo "错误: 请使用 sudo 运行,例如: sudo $0 $1"
|
||||||
|
|||||||
@@ -1,4 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 在 Debian/Ubuntu 上安装 Docker CE(支持国内/国外镜像源)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: docker-install
|
||||||
|
|
||||||
|
在 Debian 或 Ubuntu 上安装 Docker CE 及 compose/buildx 插件。
|
||||||
|
根据环境变量 CN_REGION 选择镜像源:
|
||||||
|
CN_REGION=1 清华镜像
|
||||||
|
其他 Docker 官方源
|
||||||
|
|
||||||
|
安装完成后将当前用户加入 docker 组。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -38,8 +61,6 @@ install_prerequisites() {
|
|||||||
sudo apt-get install -y ca-certificates curl gnupg lsb-release
|
sudo apt-get install -y ca-certificates curl gnupg lsb-release
|
||||||
}
|
}
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# 国内安装(使用清华镜像)
|
|
||||||
install_docker_cn() {
|
install_docker_cn() {
|
||||||
local repo_base="https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/${DISTRO}"
|
local repo_base="https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/${DISTRO}"
|
||||||
local keyring="/usr/share/keyrings/docker-archive-keyring.gpg"
|
local keyring="/usr/share/keyrings/docker-archive-keyring.gpg"
|
||||||
@@ -56,8 +77,6 @@ install_docker_cn() {
|
|||||||
sudo usermod -aG docker "$USER"
|
sudo usermod -aG docker "$USER"
|
||||||
}
|
}
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# 国外安装(使用官方源)
|
|
||||||
install_docker_intl() {
|
install_docker_intl() {
|
||||||
local repo_base="https://download.docker.com/linux/${DISTRO}"
|
local repo_base="https://download.docker.com/linux/${DISTRO}"
|
||||||
local keyring="/etc/apt/keyrings/docker.asc"
|
local keyring="/etc/apt/keyrings/docker.asc"
|
||||||
@@ -81,7 +100,6 @@ detect_distro
|
|||||||
remove_conflicting_packages
|
remove_conflicting_packages
|
||||||
install_prerequisites
|
install_prerequisites
|
||||||
|
|
||||||
# 根据环境变量选择安装方式(须在函数定义之后调用)
|
|
||||||
if [ "$CN_REGION" = "1" ]; then
|
if [ "$CN_REGION" = "1" ]; then
|
||||||
echo "[INFO] 国内环境,使用清华镜像安装 Docker (${DISTRO}/${CODENAME})"
|
echo "[INFO] 国内环境,使用清华镜像安装 Docker (${DISTRO}/${CODENAME})"
|
||||||
install_docker_cn
|
install_docker_cn
|
||||||
|
|||||||
@@ -1,4 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 下载 Fira Code 字体压缩包并打开所在目录(需手动安装)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: firacode-install
|
||||||
|
|
||||||
|
从 GitHub 下载 Fira Code v6.2 到 ~/Downloads/,并打开 Finder/文件管理器。
|
||||||
|
需在图形界面中解压并安装字体文件。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
cd ~/Downloads/
|
cd ~/Downloads/
|
||||||
wget https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip
|
wget https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip
|
||||||
|
|||||||
+26
-14
@@ -1,4 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 初始化 Fish:wrapper 配置、链接 functions/completions、安装 fisher/z
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: fish-init
|
||||||
|
|
||||||
|
1. 确保 ~/.config/fish/config.fish source dotfile/fish/default.fish
|
||||||
|
2. 链接 dotfile 中 fish functions 与 completions
|
||||||
|
3. 安装 fisher、z 插件
|
||||||
|
4. 将默认 shell 设为 fish
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
LOCAL_CONFIG="$HOME/.config/fish/config.fish"
|
LOCAL_CONFIG="$HOME/.config/fish/config.fish"
|
||||||
DEFAULT_PATH="$HOME/.dotfile/fish/default.fish"
|
DEFAULT_PATH="$HOME/.dotfile/fish/default.fish"
|
||||||
@@ -8,43 +29,36 @@ mkdir -p "$HOME/.config/fish"
|
|||||||
|
|
||||||
echo 'Setup fish config.fish wrapper'
|
echo 'Setup fish config.fish wrapper'
|
||||||
|
|
||||||
# 旧版迁移:如果 config.fish 是指向 dotfile 的 symlink(老布局),移除
|
|
||||||
if [ -L "$LOCAL_CONFIG" ]; then
|
if [ -L "$LOCAL_CONFIG" ]; then
|
||||||
link_target=$(readlink "$LOCAL_CONFIG")
|
link_target=$(readlink "$LOCAL_CONFIG")
|
||||||
case "$link_target" in
|
case "$link_target" in
|
||||||
*/dotfile/fish/config.fish|*/dotfile/fish/default.fish)
|
*/dotfile/fish/config.fish | */dotfile/fish/default.fish)
|
||||||
echo " Removing legacy symlink: $LOCAL_CONFIG -> $link_target"
|
echo " Removing legacy symlink: $LOCAL_CONFIG -> $link_target"
|
||||||
rm "$LOCAL_CONFIG"
|
rm "$LOCAL_CONFIG"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 不存在 -> 创建只含一行 source 的本地 wrapper
|
|
||||||
# 存在但未 source default.fish -> 在文件顶部插入 source 行
|
|
||||||
# 已 source -> 跳过
|
|
||||||
if [ ! -f "$LOCAL_CONFIG" ]; then
|
if [ ! -f "$LOCAL_CONFIG" ]; then
|
||||||
echo "$SOURCE_LINE" > "$LOCAL_CONFIG"
|
echo "$SOURCE_LINE" >"$LOCAL_CONFIG"
|
||||||
echo " Created $LOCAL_CONFIG (sources default.fish)"
|
echo " Created $LOCAL_CONFIG (sources default.fish)"
|
||||||
elif ! grep -qE '^[[:space:]]*source.*default\.fish' "$LOCAL_CONFIG"; then
|
elif ! grep -qE '^[[:space:]]*source.*default\.fish' "$LOCAL_CONFIG"; then
|
||||||
tmp=$(mktemp)
|
tmp=$(mktemp)
|
||||||
{ echo "$SOURCE_LINE"; echo; cat "$LOCAL_CONFIG"; } > "$tmp"
|
{ echo "$SOURCE_LINE"; echo; cat "$LOCAL_CONFIG"; } >"$tmp"
|
||||||
mv "$tmp" "$LOCAL_CONFIG"
|
mv "$tmp" "$LOCAL_CONFIG"
|
||||||
echo " Prepended source line to existing $LOCAL_CONFIG"
|
echo " Prepended source line to existing $LOCAL_CONFIG"
|
||||||
else
|
else
|
||||||
echo " $LOCAL_CONFIG already sources default.fish, skip"
|
echo " $LOCAL_CONFIG already sources default.fish, skip"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 确保目标目录存在
|
|
||||||
echo 'Link fish functions and completions'
|
echo 'Link fish functions and completions'
|
||||||
mkdir -p "$HOME/.config/fish/functions"
|
mkdir -p "$HOME/.config/fish/functions"
|
||||||
mkdir -p "$HOME/.config/fish/completions"
|
mkdir -p "$HOME/.config/fish/completions"
|
||||||
|
|
||||||
# 链接 functions 目录下的所有文件
|
|
||||||
for file in $HOME/.dotfile/fish/functions/*.fish; do
|
for file in $HOME/.dotfile/fish/functions/*.fish; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
filename=$(basename "$file")
|
filename=$(basename "$file")
|
||||||
target="$HOME/.config/fish/functions/$filename"
|
target="$HOME/.config/fish/functions/$filename"
|
||||||
# 如果已存在且不是符号链接,备份
|
|
||||||
if [ -f "$target" ] && [ ! -L "$target" ]; then
|
if [ -f "$target" ] && [ ! -L "$target" ]; then
|
||||||
mv "$target" "$target.bak"
|
mv "$target" "$target.bak"
|
||||||
fi
|
fi
|
||||||
@@ -53,12 +67,10 @@ for file in $HOME/.dotfile/fish/functions/*.fish; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# 链接 completions 目录下的所有文件
|
|
||||||
for file in $HOME/.dotfile/fish/completions/*.fish; do
|
for file in $HOME/.dotfile/fish/completions/*.fish; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
filename=$(basename "$file")
|
filename=$(basename "$file")
|
||||||
target="$HOME/.config/fish/completions/$filename"
|
target="$HOME/.config/fish/completions/$filename"
|
||||||
# 如果已存在且不是符号链接,备份
|
|
||||||
if [ -f "$target" ] && [ ! -L "$target" ]; then
|
if [ -f "$target" ] && [ ! -L "$target" ]; then
|
||||||
mv "$target" "$target.bak"
|
mv "$target" "$target.bak"
|
||||||
fi
|
fi
|
||||||
@@ -72,5 +84,5 @@ fish -c "fisher install jethrokuan/z"
|
|||||||
|
|
||||||
echo 'Set fish as default shell'
|
echo 'Set fish as default shell'
|
||||||
fishpath=$(which fish)
|
fishpath=$(which fish)
|
||||||
echo $fishpath | sudo tee -a /etc/shells
|
echo "$fishpath" | sudo tee -a /etc/shells
|
||||||
chsh -s $fishpath
|
chsh -s "$fishpath"
|
||||||
|
|||||||
+51
-25
@@ -1,83 +1,109 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# 下载并安装 Sarasa Nerd / Fira Code 字体到用户字体目录
|
||||||
|
|
||||||
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Dict, List, Optional
|
import sys
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import zipfile
|
import zipfile
|
||||||
import shutil
|
import shutil
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
def usage_text() -> str:
|
||||||
|
return """用法: font-install
|
||||||
|
|
||||||
|
下载并安装以下字体到用户字体目录:
|
||||||
|
- Sarasa Gothic Nerd (SC)
|
||||||
|
- Fira Code
|
||||||
|
|
||||||
|
macOS: ~/Library/Fonts
|
||||||
|
Linux: ~/.local/share/fonts(安装后尝试 fc-cache)
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_font_dir() -> str:
|
def get_font_dir() -> str:
|
||||||
"""根据操作系统确定字体安装目录"""
|
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == "Darwin": # macOS
|
if system == "Darwin":
|
||||||
return os.path.expanduser("~/Library/Fonts")
|
return os.path.expanduser("~/Library/Fonts")
|
||||||
elif system == "Linux":
|
if system == "Linux":
|
||||||
return os.path.expanduser("~/.local/share/fonts")
|
return os.path.expanduser("~/.local/share/fonts")
|
||||||
else:
|
|
||||||
raise OSError(f"不支持的操作系统: {system}")
|
raise OSError(f"不支持的操作系统: {system}")
|
||||||
|
|
||||||
|
|
||||||
def check_command(command: str) -> bool:
|
def check_command(command: str) -> bool:
|
||||||
"""检查命令是否存在"""
|
|
||||||
return shutil.which(command) is not None
|
return shutil.which(command) is not None
|
||||||
|
|
||||||
|
|
||||||
def download_file(url: str, dest_path: str) -> None:
|
def download_file(url: str, dest_path: str) -> None:
|
||||||
"""下载文件到指定路径"""
|
|
||||||
try:
|
try:
|
||||||
urllib.request.urlretrieve(url, dest_path)
|
urllib.request.urlretrieve(url, dest_path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"下载失败: {e}")
|
print(f"下载失败: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def get_top_level_dirs(zip_file: zipfile.ZipFile) -> List[str]:
|
def get_top_level_dirs(zip_file: zipfile.ZipFile) -> List[str]:
|
||||||
"""获取 ZIP 文件中的顶级目录"""
|
return list(set(item.split("/")[0] for item in zip_file.namelist() if "/" in item))
|
||||||
return list(set(item.split('/')[0] for item in zip_file.namelist() if '/' in item))
|
|
||||||
|
|
||||||
def has_single_top_dir(zip_file: zipfile.ZipFile) -> bool:
|
def has_single_top_dir(zip_file: zipfile.ZipFile) -> bool:
|
||||||
"""检查 ZIP 文件是否只有一个顶级目录"""
|
|
||||||
top_dirs = get_top_level_dirs(zip_file)
|
top_dirs = get_top_level_dirs(zip_file)
|
||||||
return len(top_dirs) == 1 and all(name.startswith(top_dirs[0] + '/') for name in zip_file.namelist())
|
return len(top_dirs) == 1 and all(
|
||||||
|
name.startswith(top_dirs[0] + "/") for name in zip_file.namelist()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def unzip_file(zip_path: str, font_name: str) -> None:
|
def unzip_file(zip_path: str, font_name: str) -> None:
|
||||||
"""解压文件到指定路径,根据 ZIP 文件结构决定是否创建顶级目录"""
|
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
||||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
||||||
if has_single_top_dir(zip_ref):
|
if has_single_top_dir(zip_ref):
|
||||||
# ZIP 文件有单一顶级目录,直接解压
|
|
||||||
zip_ref.extractall("/tmp")
|
zip_ref.extractall("/tmp")
|
||||||
print(f"已解压 {font_name} 到现有顶级目录")
|
print(f"已解压 {font_name} 到现有顶级目录")
|
||||||
else:
|
else:
|
||||||
# 没有单一顶级目录,创建一个以字体名命名的目录
|
|
||||||
font_dir = os.path.join("/tmp", font_name)
|
font_dir = os.path.join("/tmp", font_name)
|
||||||
os.makedirs(font_dir, exist_ok=True)
|
os.makedirs(font_dir, exist_ok=True)
|
||||||
for file in zip_ref.namelist():
|
for file in zip_ref.namelist():
|
||||||
if not file.startswith('__MACOSX'): # 排除 macOS 系统文件
|
if not file.startswith("__MACOSX"):
|
||||||
zip_ref.extract(file, font_dir)
|
zip_ref.extract(file, font_dir)
|
||||||
print(f"已解压 {font_name} 并创建新的顶级目录")
|
print(f"已解压 {font_name} 并创建新的顶级目录")
|
||||||
|
|
||||||
|
|
||||||
def install_font(font_name: str, font_dir: str) -> None:
|
def install_font(font_name: str, font_dir: str) -> None:
|
||||||
"""安装字体到指定目录"""
|
ttf_files = [
|
||||||
# find ttf files to copy to the font_dir
|
file for file in os.listdir(f"/tmp/{font_name}") if file.endswith(".ttf")
|
||||||
ttf_files = [file for file in os.listdir(f"/tmp/{font_name}") if file.endswith(".ttf")]
|
]
|
||||||
for ttf_file in ttf_files:
|
for ttf_file in ttf_files:
|
||||||
shutil.copy(f"/tmp/{font_name}/{ttf_file}", font_dir)
|
shutil.copy(f"/tmp/{font_name}/{ttf_file}", font_dir)
|
||||||
print(f"已安装 {font_name} 到 {font_dir}")
|
print(f"已安装 {font_name} 到 {font_dir}")
|
||||||
|
|
||||||
|
|
||||||
def refresh_font_cache() -> None:
|
def refresh_font_cache() -> None:
|
||||||
"""在 Linux 系统上刷新字体缓存"""
|
|
||||||
if platform.system() == "Linux" and check_command("fc-cache"):
|
if platform.system() == "Linux" and check_command("fc-cache"):
|
||||||
subprocess.run(["fc-cache", "-f"])
|
subprocess.run(["fc-cache", "-f"], check=False)
|
||||||
print("字体缓存已刷新。")
|
print("字体缓存已刷新。")
|
||||||
else:
|
else:
|
||||||
print("警告:无法刷新字体缓存。您可能需要手动刷新。")
|
print("警告:无法刷新字体缓存。您可能需要手动刷新。")
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="下载并安装 Sarasa Nerd / Fira Code 字体",
|
||||||
|
add_help=False,
|
||||||
|
)
|
||||||
|
parser.add_argument("-h", "--help", action="store_true", help="显示帮助")
|
||||||
|
args, _ = parser.parse_known_args()
|
||||||
|
if args.help:
|
||||||
|
print(usage_text())
|
||||||
|
return
|
||||||
|
|
||||||
fonts: Dict[str, str] = {
|
fonts: Dict[str, str] = {
|
||||||
"SarasaNerd":"https://github.com/jonz94/Sarasa-Gothic-Nerd-Fonts/releases/download/v1.0.23-0/sarasa-fixed-sc-nerd-font.zip",
|
"SarasaNerd": "https://github.com/jonz94/Sarasa-Gothic-Nerd-Fonts/releases/download/v1.0.23-0/sarasa-fixed-sc-nerd-font.zip",
|
||||||
"FiraCode": "https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip"
|
"FiraCode": "https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip",
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -99,6 +125,6 @@ def main() -> None:
|
|||||||
refresh_font_cache()
|
refresh_font_cache()
|
||||||
print("安装完成。请重启您的终端或应用程序以使用新字体。")
|
print("安装完成。请重启您的终端或应用程序以使用新字体。")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
+22
-5
@@ -1,4 +1,26 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 将 Ghostty 配置链接到 dotfile(macOS / Linux)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: ghostty-init
|
||||||
|
|
||||||
|
将 ~/.dotfile/ghostty/config.ghostty 软链接到 Ghostty 配置目录:
|
||||||
|
macOS: ~/Library/Application Support/com.mitchellh.ghostty/
|
||||||
|
Linux: $XDG_CONFIG_HOME/ghostty/
|
||||||
|
|
||||||
|
已有配置会备份为 *.backup.<时间戳>。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -9,7 +31,6 @@ NC='\033[0m'
|
|||||||
|
|
||||||
SRC="$HOME/.dotfile/ghostty/config.ghostty"
|
SRC="$HOME/.dotfile/ghostty/config.ghostty"
|
||||||
|
|
||||||
# 根据平台确定目标路径
|
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
if [[ "$(uname)" == "Darwin" ]]; then
|
||||||
DEST="$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty"
|
DEST="$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty"
|
||||||
else
|
else
|
||||||
@@ -20,22 +41,18 @@ fi
|
|||||||
echo -e "${YELLOW}初始化 Ghostty 配置...${NC}"
|
echo -e "${YELLOW}初始化 Ghostty 配置...${NC}"
|
||||||
echo -e "${YELLOW}目标路径:$DEST${NC}"
|
echo -e "${YELLOW}目标路径:$DEST${NC}"
|
||||||
|
|
||||||
# 目标目录不存在则创建
|
|
||||||
mkdir -p "$(dirname "$DEST")"
|
mkdir -p "$(dirname "$DEST")"
|
||||||
|
|
||||||
# 已经是指向正确位置的软链接,无需操作
|
|
||||||
if [ -L "$DEST" ] && [ "$(readlink -f "$DEST")" = "$(readlink -f "$SRC")" ]; then
|
if [ -L "$DEST" ] && [ "$(readlink -f "$DEST")" = "$(readlink -f "$SRC")" ]; then
|
||||||
echo -e "${GREEN}软链接已存在且指向正确位置,无需操作。${NC}"
|
echo -e "${GREEN}软链接已存在且指向正确位置,无需操作。${NC}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 存在旧文件/目录则备份
|
|
||||||
if [ -e "$DEST" ]; then
|
if [ -e "$DEST" ]; then
|
||||||
BACKUP="${DEST}.backup.$(date +%Y%m%d%H%M%S)"
|
BACKUP="${DEST}.backup.$(date +%Y%m%d%H%M%S)"
|
||||||
mv "$DEST" "$BACKUP"
|
mv "$DEST" "$BACKUP"
|
||||||
echo -e "${YELLOW}已将现有配置备份到 $BACKUP${NC}"
|
echo -e "${YELLOW}已将现有配置备份到 $BACKUP${NC}"
|
||||||
elif [ -L "$DEST" ]; then
|
elif [ -L "$DEST" ]; then
|
||||||
# 损坏的旧软链接
|
|
||||||
rm "$DEST"
|
rm "$DEST"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+24
-4
@@ -1,11 +1,31 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 将 ~/.gitconfig 链接到 dotfile,并设置 Linux 凭据脚本可执行
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: git-init
|
||||||
|
|
||||||
|
备份已有 ~/.gitconfig,软链接到 ~/.dotfile/git/.gitconfig。
|
||||||
|
同时为 git-credential-linux.sh 添加可执行权限。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
echo 'Init git config'
|
echo 'Init git config'
|
||||||
src=$HOME/.gitconfig
|
src=$HOME/.gitconfig
|
||||||
if [ -f $src ]; then
|
if [ -f "$src" ]; then
|
||||||
mv $src $src.bak
|
mv "$src" "$src.bak"
|
||||||
fi
|
fi
|
||||||
ln -s $HOME/.dotfile/git/.gitconfig $src
|
ln -s "$HOME/.dotfile/git/.gitconfig" "$src"
|
||||||
|
|
||||||
chmod +x "$HOME/.dotfile/git/git-credential-linux.sh"
|
chmod +x "$HOME/.dotfile/git/git-credential-linux.sh"
|
||||||
|
|
||||||
|
|||||||
+21
-22
@@ -1,32 +1,31 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 安装 gvm(Go 版本管理)并配置 fish 与默认 Go 版本
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: gvm-install
|
||||||
|
|
||||||
|
1. 安装 gvm
|
||||||
|
2. 为 fish 安装 fish-gvm、bass 插件
|
||||||
|
3. 安装并设置 go1.24.0 为默认版本
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# install gvm
|
|
||||||
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
|
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
|
||||||
|
|
||||||
# install gvm on fish
|
|
||||||
fish -c "fisher install JGAntunes/fish-gvm"
|
fish -c "fisher install JGAntunes/fish-gvm"
|
||||||
fish -c "fisher install edc/bass"
|
fish -c "fisher install edc/bass"
|
||||||
|
|
||||||
# install go
|
|
||||||
fish -c "gvm install go1.24.0 -B"
|
fish -c "gvm install go1.24.0 -B"
|
||||||
fish -c "gvm use go1.24.0 --default"
|
fish -c "gvm use go1.24.0 --default"
|
||||||
|
|
||||||
# # install neovim
|
|
||||||
# os_arch=$(uname -s)-$(uname -m)
|
|
||||||
|
|
||||||
# case $os_arch in
|
|
||||||
# "Darwin-x86_64")
|
|
||||||
# cd /usr/local
|
|
||||||
# wget https://golang.google.cn/dl/go1.23.2.linux-amd64.tar.gz
|
|
||||||
# tar zxvf go1.23.2.linux-amd64.tar.gz
|
|
||||||
# ;;
|
|
||||||
# "Linux-x86_64"|"Linux-arm64")
|
|
||||||
# cd /tmp
|
|
||||||
# rm -rf nvim-linux64.tar.gz
|
|
||||||
# wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gz
|
|
||||||
# tar zxvf go1.23.2.linux-amd64.tar.gz
|
|
||||||
# mv go /usr/local/
|
|
||||||
# sudo ln -s /usr/local/go/bin/go/usr/local/bin/go
|
|
||||||
# ;;
|
|
||||||
# esac
|
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# 初始化默认用户脚本
|
# 初始化默认用户脚本:创建 ace 用户并给予 sudo 权限
|
||||||
# 用于创建 ace 用户并给予 sudo 权限
|
|
||||||
|
|
||||||
set -e # 遇到错误时立即退出
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: sudo init-default-user
|
||||||
|
|
||||||
|
创建用户 ace(若不存在),设置密码,加入 sudo 组,
|
||||||
|
并复制 ~/.dotfile 到该用户家目录。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
# 检查是否以 root 身份运行
|
# 检查是否以 root 身份运行
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
|||||||
@@ -1,4 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 安装 lazygit(brew / apt / GitHub Release 二进制)
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: lazygit-install
|
||||||
|
|
||||||
|
按顺序尝试安装 lazygit:
|
||||||
|
1. Homebrew (macOS/Linux)
|
||||||
|
2. apt (Debian/Ubuntu)
|
||||||
|
3. 从 GitHub Release 下载到 ~/.local/bin
|
||||||
|
|
||||||
|
若已安装则打印版本并退出。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -30,7 +53,6 @@ install_via_apt() {
|
|||||||
sudo apt-get install -y lazygit
|
sudo apt-get install -y lazygit
|
||||||
}
|
}
|
||||||
|
|
||||||
# 从 GitHub Release 解压到 ~/.local/bin(与 nvim/init.lua 中的 PATH 一致)
|
|
||||||
install_via_release() {
|
install_via_release() {
|
||||||
local ver
|
local ver
|
||||||
ver=$(curl -fsSL "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" |
|
ver=$(curl -fsSL "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" |
|
||||||
@@ -72,7 +94,7 @@ install_via_release() {
|
|||||||
|
|
||||||
echo -e "${GREEN}已安装到 ${dest_bin}/lazygit${NC}"
|
echo -e "${GREEN}已安装到 ${dest_bin}/lazygit${NC}"
|
||||||
if [[ ":${PATH}:" != *":${dest_bin}:"* ]]; then
|
if [[ ":${PATH}:" != *":${dest_bin}:"* ]]; then
|
||||||
echo -e "${YELLOW}提示: 请将 ${dest_bin} 加入 PATH(例如在 ~/.zshrc 中 export PATH=\"\$HOME/.local/bin:\$PATH\")${NC}"
|
echo -e "${YELLOW}提示: 请将 ${dest_bin} 加入 PATH${NC}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +106,7 @@ main() {
|
|||||||
elif install_via_release; then
|
elif install_via_release; then
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
echo -e "${RED}lazygit 安装失败:未找到 brew/apt,且当前平台无法使用官方二进制发布包。${NC}" >&2
|
echo -e "${RED}lazygit 安装失败${NC}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+32
-18
@@ -1,15 +1,34 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source $HOME/.dotfile/script/common/os-arch.sh
|
# 下载并安装 mihomo 代理内核到 /usr/local/bin
|
||||||
|
|
||||||
# 检查并安装 gunzip
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
function check_gunzip() {
|
# shellcheck disable=SC1091
|
||||||
if ! command -v gunzip &> /dev/null; then
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: mihomo-install
|
||||||
|
|
||||||
|
根据当前 OS/架构从镜像下载 mihomo 二进制,安装到 /usr/local/bin/mihomo。
|
||||||
|
支持 darwin/linux 的 amd64/arm64。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/common/os-arch.sh"
|
||||||
|
|
||||||
|
check_gunzip() {
|
||||||
|
if ! command -v gunzip &>/dev/null; then
|
||||||
echo "gunzip 未安装,正在安装..."
|
echo "gunzip 未安装,正在安装..."
|
||||||
if command -v apt-get &> /dev/null; then
|
if command -v apt-get &>/dev/null; then
|
||||||
sudo apt-get update && sudo apt-get install -y gzip
|
sudo apt-get update && sudo apt-get install -y gzip
|
||||||
elif command -v yum &> /dev/null; then
|
elif command -v yum &>/dev/null; then
|
||||||
sudo yum install -y gzip
|
sudo yum install -y gzip
|
||||||
elif command -v brew &> /dev/null; then
|
elif command -v brew &>/dev/null; then
|
||||||
brew install gzip
|
brew install gzip
|
||||||
else
|
else
|
||||||
echo "错误: 无法安装 gunzip,请手动安装 gzip 工具"
|
echo "错误: 无法安装 gunzip,请手动安装 gzip 工具"
|
||||||
@@ -18,13 +37,14 @@ function check_gunzip() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function install_mihomo() {
|
install_mihomo() {
|
||||||
local os_arch=$(get_os_arch)
|
local os_arch
|
||||||
|
os_arch=$(get_os_arch)
|
||||||
local base_url="https://oss-default.yumee.top/bin/mihomo"
|
local base_url="https://oss-default.yumee.top/bin/mihomo"
|
||||||
local url=""
|
local url=""
|
||||||
|
|
||||||
case $os_arch in
|
case $os_arch in
|
||||||
"darwin-amd64"|"darwin-arm64"|"linux-amd64"|"linux-arm64")
|
"darwin-amd64" | "darwin-arm64" | "linux-amd64" | "linux-arm64")
|
||||||
url="${base_url}/mihomo-${os_arch}.gz"
|
url="${base_url}/mihomo-${os_arch}.gz"
|
||||||
echo "正在为 ${os_arch} 平台安装 mihomo..."
|
echo "正在为 ${os_arch} 平台安装 mihomo..."
|
||||||
;;
|
;;
|
||||||
@@ -34,14 +54,12 @@ function install_mihomo() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# 检查 gunzip 命令
|
|
||||||
check_gunzip
|
check_gunzip
|
||||||
|
|
||||||
# 创建临时目录
|
local temp_dir
|
||||||
local temp_dir=$(mktemp -d)
|
temp_dir=$(mktemp -d)
|
||||||
local temp_file="${temp_dir}/mihomo.gz"
|
local temp_file="${temp_dir}/mihomo.gz"
|
||||||
|
|
||||||
# 下载文件
|
|
||||||
echo "正在从 ${url} 下载..."
|
echo "正在从 ${url} 下载..."
|
||||||
if ! curl -L -o "${temp_file}" "${url}"; then
|
if ! curl -L -o "${temp_file}" "${url}"; then
|
||||||
echo "错误: 下载失败"
|
echo "错误: 下载失败"
|
||||||
@@ -49,7 +67,6 @@ function install_mihomo() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 解压文件
|
|
||||||
echo "正在解压..."
|
echo "正在解压..."
|
||||||
if ! gunzip "${temp_file}"; then
|
if ! gunzip "${temp_file}"; then
|
||||||
echo "错误: 解压失败"
|
echo "错误: 解压失败"
|
||||||
@@ -57,17 +74,14 @@ function install_mihomo() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 移动到 /usr/local/bin 并设置执行权限
|
|
||||||
local binary="${temp_dir}/mihomo"
|
local binary="${temp_dir}/mihomo"
|
||||||
echo "正在安装到 /usr/local/bin/mihomo..."
|
echo "正在安装到 /usr/local/bin/mihomo..."
|
||||||
sudo mv "${binary}" /usr/local/bin/mihomo
|
sudo mv "${binary}" /usr/local/bin/mihomo
|
||||||
sudo chmod +x /usr/local/bin/mihomo
|
sudo chmod +x /usr/local/bin/mihomo
|
||||||
|
|
||||||
# 清理临时文件
|
|
||||||
rm -rf "${temp_dir}"
|
rm -rf "${temp_dir}"
|
||||||
|
|
||||||
echo "mihomo 安装完成!"
|
echo "mihomo 安装完成!"
|
||||||
echo "版本信息:"
|
|
||||||
/usr/local/bin/mihomo version || echo "mihomo 已安装到 /usr/local/bin/mihomo"
|
/usr/local/bin/mihomo version || echo "mihomo 已安装到 /usr/local/bin/mihomo"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-22
@@ -1,30 +1,45 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 安装 mise 并链接 dotfile 配置、安装 config.toml 中的工具
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: mise-install
|
||||||
|
|
||||||
|
1. 若未安装则通过官方脚本安装 mise
|
||||||
|
2. 链接 ~/.dotfile/mise/config.toml
|
||||||
|
3. 执行 mise install 安装配置中的工具
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# 设置颜色
|
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m'
|
||||||
|
|
||||||
# 检查是否已安装 mise
|
if ! command -v mise &>/dev/null; then
|
||||||
if ! command -v mise &> /dev/null
|
|
||||||
then
|
|
||||||
echo -e "${YELLOW}mise 未安装. 正在安装 mise...${NC}"
|
echo -e "${YELLOW}mise 未安装. 正在安装 mise...${NC}"
|
||||||
# 安装 mise(官方安装脚本会自动配置 shell)
|
|
||||||
curl https://mise.run | sh
|
curl https://mise.run | sh
|
||||||
|
|
||||||
# 重新加载当前 shell 环境
|
|
||||||
export PATH="$HOME/.local/bin:$PATH"
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
|
||||||
# 如果安装脚本没有自动配置,手动配置 fish shell(如果存在)
|
|
||||||
if [ -f ~/.config/fish/config.fish ]; then
|
if [ -f ~/.config/fish/config.fish ]; then
|
||||||
if ! grep -q "mise activate" ~/.config/fish/config.fish; then
|
if ! grep -q "mise activate" ~/.config/fish/config.fish; then
|
||||||
echo -e "${YELLOW}正在为 fish shell 配置 mise...${NC}"
|
echo -e "${YELLOW}正在为 fish shell 配置 mise...${NC}"
|
||||||
echo '' >> ~/.config/fish/config.fish
|
{
|
||||||
echo '# mise (formerly rtx)' >> ~/.config/fish/config.fish
|
echo ''
|
||||||
echo 'mise activate fish | source' >> ~/.config/fish/config.fish
|
echo '# mise (formerly rtx)'
|
||||||
|
echo 'mise activate fish | source'
|
||||||
|
} >>~/.config/fish/config.fish
|
||||||
echo -e "${GREEN}已将 mise 添加到 ~/.config/fish/config.fish${NC}"
|
echo -e "${GREEN}已将 mise 添加到 ~/.config/fish/config.fish${NC}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -35,7 +50,6 @@ else
|
|||||||
mise --version
|
mise --version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 链接 dotfile 中的 mise 配置
|
|
||||||
MISE_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/mise"
|
MISE_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/mise"
|
||||||
DOTFILE_MISE_CONFIG="$HOME/.dotfile/mise/config.toml"
|
DOTFILE_MISE_CONFIG="$HOME/.dotfile/mise/config.toml"
|
||||||
mkdir -p "$MISE_CONFIG_DIR"
|
mkdir -p "$MISE_CONFIG_DIR"
|
||||||
@@ -49,22 +63,15 @@ if [ -f "$DOTFILE_MISE_CONFIG" ]; then
|
|||||||
mise trust "$DOTFILE_MISE_CONFIG" 2>/dev/null || true
|
mise trust "$DOTFILE_MISE_CONFIG" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 安装配置中的工具
|
if command -v mise &>/dev/null && [ -f "$MISE_CONFIG_DIR/config.toml" ]; then
|
||||||
if command -v mise &> /dev/null && [ -f "$MISE_CONFIG_DIR/config.toml" ]; then
|
|
||||||
echo -e "${YELLOW}正在安装 mise 工具...${NC}"
|
echo -e "${YELLOW}正在安装 mise 工具...${NC}"
|
||||||
mise install
|
mise install
|
||||||
echo -e "${GREEN}mise 工具安装完成${NC}"
|
echo -e "${GREEN}mise 工具安装完成${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 验证安装
|
if command -v mise &>/dev/null; then
|
||||||
if command -v mise &> /dev/null
|
|
||||||
then
|
|
||||||
echo -e "${GREEN}mise 安装成功!${NC}"
|
echo -e "${GREEN}mise 安装成功!${NC}"
|
||||||
echo -e "${YELLOW}提示: 如果 mise 命令不可用,请重新打开终端或运行:${NC}"
|
|
||||||
echo -e "${GREEN}export PATH=\"\$HOME/.local/bin:\$PATH\"${NC}"
|
|
||||||
echo -e "${YELLOW}或者重新加载 shell 配置文件${NC}"
|
|
||||||
else
|
else
|
||||||
echo -e "${RED}mise 安装失败,请检查错误信息${NC}"
|
echo -e "${RED}mise 安装失败,请检查错误信息${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -1,7 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# 为指定用户配置某命令的免密 sudo(写入 /etc/sudoers.d/)
|
# 为指定用户配置某命令的免密 sudo(写入 /etc/sudoers.d/)
|
||||||
# 用法: sudo nosudo <user> <command>
|
|
||||||
# 示例: sudo nosudo xuser docker
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -21,12 +23,14 @@ usage() {
|
|||||||
- 仅允许免密执行解析到的那个可执行文件路径(含子命令参数仍受 sudo 规则约束)
|
- 仅允许免密执行解析到的那个可执行文件路径(含子命令参数仍受 sudo 规则约束)
|
||||||
- 对 docker,更推荐: sudo docker-group <user>(无需 sudo 即可用 docker)
|
- 对 docker,更推荐: sudo docker-group <user>(无需 sudo 即可用 docker)
|
||||||
- 删除规则: sudo rm /etc/sudoers.d/nosudo-<user>-<name>
|
- 删除规则: sudo rm /etc/sudoers.d/nosudo-<user>-<name>
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]] && usage
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
[[ $# -eq 2 ]] || usage
|
[[ $# -eq 2 ]] || { usage; exit 1; }
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "错误: 请使用 sudo 运行,例如: sudo $0 $*"
|
echo "错误: 请使用 sudo 运行,例如: sudo $0 $*"
|
||||||
|
|||||||
+21
-10
@@ -1,38 +1,49 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 将 Neovim 配置目录链接到 dotfile/nvim
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: nvim-init
|
||||||
|
|
||||||
|
将 ~/.config/nvim 软链接到 ~/.dotfile/nvim。
|
||||||
|
已有配置会备份为 nvim.backup.<时间戳>。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
# 定义变量
|
|
||||||
NVIM_CONFIG_DIR="$HOME/.config/nvim"
|
NVIM_CONFIG_DIR="$HOME/.config/nvim"
|
||||||
YOUR_CUSTOM_CONFIG_DIR="$HOME/.dotfile/nvim" # 请替换为您的自定义配置目录路径
|
YOUR_CUSTOM_CONFIG_DIR="$HOME/.dotfile/nvim"
|
||||||
|
|
||||||
# 检查软链接是否已经存在并指向正确的目录
|
|
||||||
if [ -L "$NVIM_CONFIG_DIR" ] && [ "$(readlink -f "$NVIM_CONFIG_DIR")" = "$(readlink -f "$YOUR_CUSTOM_CONFIG_DIR")" ]; then
|
if [ -L "$NVIM_CONFIG_DIR" ] && [ "$(readlink -f "$NVIM_CONFIG_DIR")" = "$(readlink -f "$YOUR_CUSTOM_CONFIG_DIR")" ]; then
|
||||||
echo "软链接已经存在并指向正确的目录。无需进行任何操作。"
|
echo "软链接已经存在并指向正确的目录。无需进行任何操作。"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查是否存在现有的 Neovim 配置
|
|
||||||
if [ -e "$NVIM_CONFIG_DIR" ]; then
|
if [ -e "$NVIM_CONFIG_DIR" ]; then
|
||||||
echo "检测到现有的 Neovim 配置。"
|
echo "检测到现有的 Neovim 配置。"
|
||||||
|
|
||||||
# 如果是目录或常规文件,创建备份
|
|
||||||
if [ -d "$NVIM_CONFIG_DIR" ] || [ -f "$NVIM_CONFIG_DIR" ]; then
|
if [ -d "$NVIM_CONFIG_DIR" ] || [ -f "$NVIM_CONFIG_DIR" ]; then
|
||||||
BACKUP_DIR="$NVIM_CONFIG_DIR.backup.$(date +%Y%m%d%H%M%S)"
|
BACKUP_DIR="$NVIM_CONFIG_DIR.backup.$(date +%Y%m%d%H%M%S)"
|
||||||
mv "$NVIM_CONFIG_DIR" "$BACKUP_DIR"
|
mv "$NVIM_CONFIG_DIR" "$BACKUP_DIR"
|
||||||
echo "已将现有配置备份到 $BACKUP_DIR"
|
echo "已将现有配置备份到 $BACKUP_DIR"
|
||||||
else
|
else
|
||||||
# 如果是其他类型的文件(如损坏的软链接),直接删除
|
|
||||||
rm "$NVIM_CONFIG_DIR"
|
rm "$NVIM_CONFIG_DIR"
|
||||||
echo "已删除现有的无效配置。"
|
echo "已删除现有的无效配置。"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 创建软链接
|
|
||||||
ln -s "$YOUR_CUSTOM_CONFIG_DIR" "$NVIM_CONFIG_DIR"
|
ln -s "$YOUR_CUSTOM_CONFIG_DIR" "$NVIM_CONFIG_DIR"
|
||||||
|
|
||||||
# 检查软链接是否创建成功
|
|
||||||
if [ -L "$NVIM_CONFIG_DIR" ] && [ "$(readlink -f "$NVIM_CONFIG_DIR")" = "$(readlink -f "$YOUR_CUSTOM_CONFIG_DIR")" ]; then
|
if [ -L "$NVIM_CONFIG_DIR" ] && [ "$(readlink -f "$NVIM_CONFIG_DIR")" = "$(readlink -f "$YOUR_CUSTOM_CONFIG_DIR")" ]; then
|
||||||
echo "软链接创建成功。Neovim 现在将使用您的自定义配置。"
|
echo "软链接创建成功。Neovim 现在将使用您的自定义配置。"
|
||||||
else
|
else
|
||||||
echo "创建软链接时出错。请检查路径和权限。"
|
echo "创建软链接时出错。请检查路径和权限。"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+30
-18
@@ -1,8 +1,28 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 从 GitHub Release 安装 Neovim 到 /usr/local/nvim
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: nvim-install
|
||||||
|
|
||||||
|
按当前平台下载 Neovim v0.12.2 预编译包,安装到 /usr/local/nvim,
|
||||||
|
并链接 nvim/vim 到 /usr/local/bin。
|
||||||
|
|
||||||
|
支持: macOS x86_64/arm64, Linux x86_64/arm64
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# install neovim
|
|
||||||
os_arch=$(uname -s)-$(uname -m)
|
os_arch=$(uname -s)-$(uname -m)
|
||||||
ver=v0.12.2
|
ver=v0.12.2
|
||||||
|
|
||||||
@@ -10,57 +30,49 @@ case $os_arch in
|
|||||||
"Darwin-x86_64")
|
"Darwin-x86_64")
|
||||||
cd /tmp
|
cd /tmp
|
||||||
rm -rf nvim-macos-x86_64.tar.gz
|
rm -rf nvim-macos-x86_64.tar.gz
|
||||||
wget https://github.com/neovim/neovim/releases/download/$ver/nvim-macos-x86_64.tar.gz
|
wget "https://github.com/neovim/neovim/releases/download/$ver/nvim-macos-x86_64.tar.gz"
|
||||||
tar zxf nvim-macos-x86_64.tar.gz
|
tar zxf nvim-macos-x86_64.tar.gz
|
||||||
sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
sudo mv -f /usr/local/nvim /usr/local/nvim-bak 2>/dev/null || true
|
||||||
sudo mv nvim-macos-x86_64 /usr/local/nvim
|
sudo mv nvim-macos-x86_64 /usr/local/nvim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
||||||
echo ""
|
|
||||||
vim -v
|
vim -v
|
||||||
;;
|
;;
|
||||||
"Darwin-arm64" | "Darwin-aarch64")
|
"Darwin-arm64" | "Darwin-aarch64")
|
||||||
cd /tmp
|
cd /tmp
|
||||||
rm -rf nvim-macos-arm64.tar.gz
|
rm -rf nvim-macos-arm64.tar.gz
|
||||||
wget https://github.com/neovim/neovim/releases/download/$ver/nvim-macos-arm64.tar.gz
|
wget "https://github.com/neovim/neovim/releases/download/$ver/nvim-macos-arm64.tar.gz"
|
||||||
tar zxf nvim-macos-arm64.tar.gz
|
tar zxf nvim-macos-arm64.tar.gz
|
||||||
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
||||||
sudo mv nvim-macos-arm64 /usr/local/nvim
|
sudo mv nvim-macos-arm64 /usr/local/nvim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
||||||
echo ""
|
|
||||||
vim -v
|
vim -v
|
||||||
;;
|
;;
|
||||||
"Linux-x86_64")
|
"Linux-x86_64")
|
||||||
cd /tmp
|
cd /tmp
|
||||||
rm -rf nvim-linux64.tar.gz
|
rm -rf nvim-linux-x86_64.tar.gz
|
||||||
wget https://github.com/neovim/neovim/releases/download/$ver/nvim-linux-x86_64.tar.gz
|
wget "https://github.com/neovim/neovim/releases/download/$ver/nvim-linux-x86_64.tar.gz"
|
||||||
tar zxf nvim-linux-x86_64.tar.gz
|
tar zxf nvim-linux-x86_64.tar.gz
|
||||||
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
||||||
sudo mv nvim-linux-x86_64 /usr/local/nvim
|
sudo mv nvim-linux-x86_64 /usr/local/nvim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
||||||
echo ""
|
|
||||||
vim -v
|
vim -v
|
||||||
;;
|
;;
|
||||||
"Linux-arm64" | "Linux-aarch64")
|
"Linux-arm64" | "Linux-aarch64")
|
||||||
cd /tmp
|
cd /tmp
|
||||||
rm -rf nvim-linux64.tar.gz
|
rm -rf nvim-linux-arm64.tar.gz
|
||||||
wget https://github.com/neovim/neovim/releases/download/$ver/nvim-linux-arm64.tar.gz
|
wget "https://github.com/neovim/neovim/releases/download/$ver/nvim-linux-arm64.tar.gz"
|
||||||
tar zxf nvim-linux64.tar.gz
|
tar zxf nvim-linux-arm64.tar.gz
|
||||||
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
[ -e /usr/local/nvim ] && sudo mv -f /usr/local/nvim /usr/local/nvim-bak
|
||||||
sudo mv nvim-linux64 /usr/local/nvim
|
sudo mv nvim-linux-arm64 /usr/local/nvim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/vim
|
||||||
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
sudo ln -sf /usr/local/nvim/bin/nvim /usr/local/bin/nvim
|
||||||
echo ""
|
|
||||||
vim -v
|
vim -v
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "不支持的平台: $os_arch" >&2
|
echo "不支持的平台: $os_arch" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# if has error "no c compile found"
|
|
||||||
# sudo apt install build-essential
|
|
||||||
|
|||||||
+27
-5
@@ -1,9 +1,31 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 安装 fnm(Node 版本管理)并 reload fish 配置
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: nvm-install
|
||||||
|
|
||||||
|
通过 fnm 官方安装脚本安装 Fast Node Manager,并执行 ff reload。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
说明: 本仓库 fish 配置中 nvm 别名指向 fnm。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# https://github.com/Schniz/fnm
|
|
||||||
curl -fsSL https://fnm.vercel.app/install | bash
|
curl -fsSL https://fnm.vercel.app/install | bash
|
||||||
|
|
||||||
ff reload
|
if command -v ff &>/dev/null; then
|
||||||
|
ff reload
|
||||||
# after install node
|
elif command -v fish &>/dev/null; then
|
||||||
# corepack enable pnpm
|
fish -c "source ~/.config/fish/config.fish"
|
||||||
|
fi
|
||||||
|
|||||||
+28
-15
@@ -1,38 +1,51 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 安装 pyenv 并配置 Python 3.11.10 及常用包
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: python-install
|
||||||
|
|
||||||
|
1. 若未安装则安装 pyenv
|
||||||
|
2. 安装 Python 3.11.10 并设为 global
|
||||||
|
3. 升级 pip 并安装 ipython/jupyter 等常用包
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# 设置颜色
|
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m'
|
||||||
|
|
||||||
# 检查是否已安装 pyenv
|
if ! command -v pyenv &>/dev/null; then
|
||||||
if ! command -v pyenv &> /dev/null
|
|
||||||
then
|
|
||||||
echo -e "${RED}pyenv 未安装. 正在安装 pyenv...${NC}"
|
echo -e "${RED}pyenv 未安装. 正在安装 pyenv...${NC}"
|
||||||
# 安装 pyenv
|
|
||||||
curl https://pyenv.run | bash
|
curl https://pyenv.run | bash
|
||||||
source ~/.config/fish/config.fish
|
if [ -f ~/.config/fish/config.fish ]; then
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source ~/.config/fish/config.fish 2>/dev/null || true
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}pyenv 已安装${NC}"
|
echo -e "${GREEN}pyenv 已安装${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 询问用户想安装的 Python 版本
|
|
||||||
python_version=3.11.10
|
python_version=3.11.10
|
||||||
|
|
||||||
# 安装指定版本的 Python
|
|
||||||
echo -e "${GREEN}正在安装 Python $python_version...${NC}"
|
echo -e "${GREEN}正在安装 Python $python_version...${NC}"
|
||||||
pyenv install $python_version
|
pyenv install "$python_version"
|
||||||
|
pyenv global "$python_version"
|
||||||
|
|
||||||
# 设置全局 Python 版本
|
|
||||||
pyenv global $python_version
|
|
||||||
|
|
||||||
# 验证安装
|
|
||||||
installed_version=$(python --version)
|
installed_version=$(python --version)
|
||||||
echo -e "${GREEN}Python 安装完成. 当前版本: $installed_version${NC}"
|
echo -e "${GREEN}Python 安装完成. 当前版本: $installed_version${NC}"
|
||||||
|
|
||||||
# 安装一些常用的 Python 包
|
|
||||||
echo -e "${GREEN}正在安装一些常用的 Python 包...${NC}"
|
echo -e "${GREEN}正在安装一些常用的 Python 包...${NC}"
|
||||||
pip install --upgrade pip
|
pip install --upgrade pip
|
||||||
pip install ipython jupyter notebook pandas numpy matplotlib scikit-learn
|
pip install ipython jupyter notebook pandas numpy matplotlib scikit-learn
|
||||||
|
|||||||
+26
-19
@@ -1,12 +1,29 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# ICMP/TCP 扫描本网段或指定网段的在线主机与开放端口
|
||||||
|
|
||||||
# 用法:
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
# ./scan-ip.sh # ICMP 扫描本网段在线 IP
|
# shellcheck disable=SC1091
|
||||||
# ./scan-ip.sh 10.0.0 # ICMP 扫描指定网段(10.0.0.1-254)
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
# ./scan-ip.sh 22 # 扫描本网段中 22 端口开放的 IP
|
|
||||||
# ./scan-ip.sh 80,443,8080 # 扫描本网段中任一指定端口开放的 IP
|
usage() {
|
||||||
# ./scan-ip.sh 22 10.0.0 # 指定网段前缀 + 端口(顺序不限)
|
cat <<'EOF'
|
||||||
# ./scan-ip.sh 10.0.0 22 # 同上
|
用法: scan-ip [端口或网段参数...]
|
||||||
|
|
||||||
|
扫描局域网主机:
|
||||||
|
无参数 ICMP 扫描本网段 .1-.254
|
||||||
|
10.0.0 扫描指定网段前缀
|
||||||
|
22 扫描本网段 TCP 22 端口
|
||||||
|
80,443,8080 扫描多个端口(任一开放即显示)
|
||||||
|
22 10.0.0 指定网段 + 端口(顺序不限)
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
依赖: ping;端口模式需要 nc (netcat)。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
TIMEOUT=1
|
TIMEOUT=1
|
||||||
|
|
||||||
@@ -31,8 +48,7 @@ fi
|
|||||||
|
|
||||||
if [ -n "$1" ] && [ -z "$PORT_SPEC" ] && [ -z "$PREFIX_ARG" ]; then
|
if [ -n "$1" ] && [ -z "$PORT_SPEC" ] && [ -z "$PREFIX_ARG" ]; then
|
||||||
echo "错误: 无法识别参数: $1"
|
echo "错误: 无法识别参数: $1"
|
||||||
echo "端口支持: 单端口(22) / 列表(80,443) / 范围(8000-8100)"
|
usage
|
||||||
echo "网段支持: 前缀(10.0.0 或 192.168.1.0)"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -52,7 +68,6 @@ else
|
|||||||
PREFIX="${LOCAL_IP%.*}"
|
PREFIX="${LOCAL_IP%.*}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 解析端口参数 -> PORTS 数组
|
|
||||||
PORTS=()
|
PORTS=()
|
||||||
if [ -n "$PORT_SPEC" ]; then
|
if [ -n "$PORT_SPEC" ]; then
|
||||||
if [[ "$PORT_SPEC" =~ ^[0-9]+$ ]]; then
|
if [[ "$PORT_SPEC" =~ ^[0-9]+$ ]]; then
|
||||||
@@ -68,7 +83,6 @@ if [ -n "$PORT_SPEC" ]; then
|
|||||||
IFS=',' read -ra PORTS <<<"$PORT_SPEC"
|
IFS=',' read -ra PORTS <<<"$PORT_SPEC"
|
||||||
else
|
else
|
||||||
echo "错误: 无效的端口格式: $PORT_SPEC"
|
echo "错误: 无效的端口格式: $PORT_SPEC"
|
||||||
echo "支持: 单端口(22) / 列表(80,443) / 范围(8000-8100)"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -81,10 +95,7 @@ else
|
|||||||
fi
|
fi
|
||||||
echo "------------------------------------------------------"
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
# ---------- 模式一:ICMP 在线扫描(无端口参数) ----------
|
|
||||||
if [ ${#PORTS[@]} -eq 0 ]; then
|
if [ ${#PORTS[@]} -eq 0 ]; then
|
||||||
# macOS: -W 单位毫秒,-S 绑定源 IP
|
|
||||||
# Linux: -W 单位秒, -I 绑定源 IP
|
|
||||||
if [ "$(uname -s)" = "Darwin" ]; then
|
if [ "$(uname -s)" = "Darwin" ]; then
|
||||||
for i in $(seq 1 254); do
|
for i in $(seq 1 254); do
|
||||||
ping -c 1 -W 1000 -S "$LOCAL_IP" "$PREFIX.$i" >/dev/null 2>&1 && echo "$PREFIX.$i 在线" &
|
ping -c 1 -W 1000 -S "$LOCAL_IP" "$PREFIX.$i" >/dev/null 2>&1 && echo "$PREFIX.$i 在线" &
|
||||||
@@ -100,15 +111,11 @@ if [ ${#PORTS[@]} -eq 0 ]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------- 模式二:TCP 端口扫描 ----------
|
|
||||||
if ! command -v nc &>/dev/null; then
|
if ! command -v nc &>/dev/null; then
|
||||||
echo "错误: 找不到 nc (netcat),请先安装:"
|
echo "错误: 找不到 nc (netcat)"
|
||||||
echo " macOS: brew install netcat"
|
|
||||||
echo " Debian/Ubuntu: sudo apt-get install netcat-openbsd"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# nc 在不同实现里 -z/-w 行为基本一致;用 -G 在 macOS 上控制连接超时更准
|
|
||||||
NC_OPTS=(-z -w "$TIMEOUT")
|
NC_OPTS=(-z -w "$TIMEOUT")
|
||||||
if [ "$(uname -s)" = "Darwin" ]; then
|
if [ "$(uname -s)" = "Darwin" ]; then
|
||||||
NC_OPTS+=(-G "$TIMEOUT")
|
NC_OPTS+=(-G "$TIMEOUT")
|
||||||
|
|||||||
+32
-36
@@ -1,25 +1,42 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 对指定 IP 进行 TCP 端口扫描
|
||||||
|
|
||||||
# 端口扫描脚本
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
# 用法: ./scan-port.sh <IP地址> [端口范围]
|
# shellcheck disable=SC1091
|
||||||
# 示例: ./scan-port.sh 192.168.1.1
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
# 示例: ./scan-port.sh 192.168.1.1 80,443,8080
|
|
||||||
# 示例: ./scan-port.sh 192.168.1.1 1-1000
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: scan-port <IP> [端口范围]
|
||||||
|
|
||||||
|
扫描目标 IP 的 TCP 端口(使用 nc)。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
IP 目标 IPv4 地址(必填)
|
||||||
|
端口范围 可选。默认扫描常用端口列表。
|
||||||
|
支持: 80,443,8080 或 1-1000
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
示例:
|
||||||
|
scan-port 192.168.1.1
|
||||||
|
scan-port 192.168.1.1 22,80,443
|
||||||
|
scan-port 192.168.1.1 1-1000
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
# 检查是否提供了 IP 地址参数
|
|
||||||
if [ -z "$1" ]; then
|
if [ -z "$1" ]; then
|
||||||
echo "错误: 请提供要扫描的 IP 地址"
|
echo "错误: 请提供要扫描的 IP 地址" >&2
|
||||||
echo "用法: $0 <IP地址> [端口范围]"
|
usage
|
||||||
echo "示例: $0 192.168.1.1"
|
|
||||||
echo "示例: $0 192.168.1.1 80,443,8080"
|
|
||||||
echo "示例: $0 192.168.1.1 1-1000"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TARGET_IP="$1"
|
TARGET_IP="$1"
|
||||||
TIMEOUT=1 # 连接超时时间(秒)
|
TIMEOUT=1
|
||||||
|
|
||||||
# 验证 IP 地址格式(简单验证)
|
|
||||||
if ! [[ "$TARGET_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
if ! [[ "$TARGET_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||||
echo "错误: 无效的 IP 地址格式: $TARGET_IP"
|
echo "错误: 无效的 IP 地址格式: $TARGET_IP"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -29,25 +46,17 @@ echo "=========================================="
|
|||||||
echo "正在扫描 IP: $TARGET_IP"
|
echo "正在扫描 IP: $TARGET_IP"
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
|
|
||||||
# 检查是否有 nc (netcat) 命令
|
|
||||||
if ! command -v nc &>/dev/null; then
|
if ! command -v nc &>/dev/null; then
|
||||||
echo "错误: 找不到 nc (netcat) 命令。"
|
echo "错误: 找不到 nc (netcat) 命令。"
|
||||||
echo "请安装 netcat:"
|
|
||||||
echo " macOS: brew install netcat"
|
|
||||||
echo " Linux: sudo apt-get install netcat 或 sudo yum install nc"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 确定要扫描的端口
|
|
||||||
if [ -z "$2" ]; then
|
if [ -z "$2" ]; then
|
||||||
# 如果没有指定端口,扫描常用端口
|
|
||||||
PORTS=(21 22 23 25 53 80 110 111 135 139 143 443 445 993 995 1723 3306 3389 5432 5900 8080 8443)
|
PORTS=(21 22 23 25 53 80 110 111 135 139 143 443 445 993 995 1723 3306 3389 5432 5900 8080 8443)
|
||||||
echo "使用默认常用端口列表"
|
echo "使用默认常用端口列表"
|
||||||
else
|
else
|
||||||
# 解析端口参数
|
|
||||||
PORT_SPEC="$2"
|
PORT_SPEC="$2"
|
||||||
|
|
||||||
# 检查是否是范围格式 (例如: 1-1000)
|
|
||||||
if [[ "$PORT_SPEC" =~ ^[0-9]+-[0-9]+$ ]]; then
|
if [[ "$PORT_SPEC" =~ ^[0-9]+-[0-9]+$ ]]; then
|
||||||
START_PORT=$(echo "$PORT_SPEC" | cut -d'-' -f1)
|
START_PORT=$(echo "$PORT_SPEC" | cut -d'-' -f1)
|
||||||
END_PORT=$(echo "$PORT_SPEC" | cut -d'-' -f2)
|
END_PORT=$(echo "$PORT_SPEC" | cut -d'-' -f2)
|
||||||
@@ -58,16 +67,12 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
PORTS=($(seq "$START_PORT" "$END_PORT"))
|
PORTS=($(seq "$START_PORT" "$END_PORT"))
|
||||||
echo "扫描端口范围: $START_PORT-$END_PORT (共 $((END_PORT - START_PORT + 1)) 个端口)"
|
echo "扫描端口范围: $START_PORT-$END_PORT"
|
||||||
# 检查是否是逗号分隔的端口列表 (例如: 80,443,8080)
|
|
||||||
elif [[ "$PORT_SPEC" =~ ^[0-9,]+$ ]]; then
|
elif [[ "$PORT_SPEC" =~ ^[0-9,]+$ ]]; then
|
||||||
IFS=',' read -ra PORTS <<< "$PORT_SPEC"
|
IFS=',' read -ra PORTS <<<"$PORT_SPEC"
|
||||||
echo "扫描指定端口: $PORT_SPEC"
|
echo "扫描指定端口: $PORT_SPEC"
|
||||||
else
|
else
|
||||||
echo "错误: 无效的端口格式: $PORT_SPEC"
|
echo "错误: 无效的端口格式: $PORT_SPEC"
|
||||||
echo "支持的格式:"
|
|
||||||
echo " - 逗号分隔: 80,443,8080"
|
|
||||||
echo " - 范围: 1-1000"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -75,20 +80,14 @@ fi
|
|||||||
echo "超时设置: ${TIMEOUT}秒"
|
echo "超时设置: ${TIMEOUT}秒"
|
||||||
echo "------------------------------------------------------"
|
echo "------------------------------------------------------"
|
||||||
|
|
||||||
# 统计变量
|
|
||||||
OPEN_PORTS=()
|
OPEN_PORTS=()
|
||||||
CLOSED_COUNT=0
|
CLOSED_COUNT=0
|
||||||
TOTAL_PORTS=${#PORTS[@]}
|
TOTAL_PORTS=${#PORTS[@]}
|
||||||
|
|
||||||
# 扫描端口函数
|
|
||||||
scan_port() {
|
scan_port() {
|
||||||
local port=$1
|
local port=$1
|
||||||
local ip=$2
|
local ip=$2
|
||||||
|
|
||||||
# 使用 nc 扫描端口
|
|
||||||
# -z: 只扫描,不发送数据
|
|
||||||
# -v: 详细输出
|
|
||||||
# -w: 超时时间
|
|
||||||
if nc -z -v -w "$TIMEOUT" "$ip" "$port" 2>&1 | grep -q "succeeded\|open"; then
|
if nc -z -v -w "$TIMEOUT" "$ip" "$port" 2>&1 | grep -q "succeeded\|open"; then
|
||||||
echo "✅ 端口 $port: 开放"
|
echo "✅ 端口 $port: 开放"
|
||||||
return 0
|
return 0
|
||||||
@@ -97,7 +96,6 @@ scan_port() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# 并行扫描端口(使用后台任务)
|
|
||||||
for port in "${PORTS[@]}"; do
|
for port in "${PORTS[@]}"; do
|
||||||
if scan_port "$port" "$TARGET_IP"; then
|
if scan_port "$port" "$TARGET_IP"; then
|
||||||
OPEN_PORTS+=("$port")
|
OPEN_PORTS+=("$port")
|
||||||
@@ -106,7 +104,6 @@ for port in "${PORTS[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# 等待所有后台任务完成
|
|
||||||
wait
|
wait
|
||||||
|
|
||||||
echo "------------------------------------------------------"
|
echo "------------------------------------------------------"
|
||||||
@@ -128,4 +125,3 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
|
|
||||||
|
|||||||
+27
-6
@@ -1,12 +1,33 @@
|
|||||||
#/bin/bash
|
#!/bin/bash
|
||||||
|
# 链接 tmux 配置并安装 TPM 插件
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: tmux-init
|
||||||
|
|
||||||
|
1. 将 ~/.tmux.conf 链接到 ~/.dotfile/tmux/.tmux.conf
|
||||||
|
2. 克隆 tpm 到 ~/.tmux/plugins/tpm(若不存在)
|
||||||
|
3. 安装插件并 reload tmux 配置
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
echo 'Init tmux config'
|
echo 'Init tmux config'
|
||||||
src=$HOME/.tmux.conf
|
src=$HOME/.tmux.conf
|
||||||
if [ -e $src ]; then
|
if [ -e "$src" ]; then
|
||||||
mv $src $src.bak
|
mv "$src" "$src.bak"
|
||||||
fi
|
fi
|
||||||
ln -s $HOME/.dotfile/tmux/.tmux.conf $src
|
ln -s "$HOME/.dotfile/tmux/.tmux.conf" "$src"
|
||||||
|
|
||||||
|
|
||||||
echo 'Install tpm'
|
echo 'Install tpm'
|
||||||
if [ ! -e ~/.tmux/plugins/tpm ]; then
|
if [ ! -e ~/.tmux/plugins/tpm ]; then
|
||||||
@@ -14,7 +35,7 @@ if [ ! -e ~/.tmux/plugins/tpm ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo 'Install tmux plugin by tpm'
|
echo 'Install tmux plugin by tpm'
|
||||||
$HOME/.tmux/plugins/tpm/bin/install_plugins
|
"$HOME/.tmux/plugins/tpm/bin/install_plugins"
|
||||||
|
|
||||||
echo 'Reload tmux'
|
echo 'Reload tmux'
|
||||||
tmux source ~/.tmux.conf
|
tmux source ~/.tmux.conf
|
||||||
+24
-3
@@ -1,6 +1,28 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# 切换 CN_REGION 环境变量
|
# 切换 CN_REGION 环境变量(国内/国外镜像与安装源)
|
||||||
# cn ↔ intl 切换
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: toggle-region
|
||||||
|
|
||||||
|
在当前 shell 中切换 CN_REGION:
|
||||||
|
1 -> 0 国内 -> 国外
|
||||||
|
0/未设置 -> 1 国外 -> 国内
|
||||||
|
|
||||||
|
影响依赖 CN_REGION 的安装脚本(如 docker-install)。
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
说明: 仅影响当前 shell 会话;持久化请写入 fish/zsh 配置。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
if [ "$CN_REGION" = "1" ]; then
|
if [ "$CN_REGION" = "1" ]; then
|
||||||
export CN_REGION=0
|
export CN_REGION=0
|
||||||
@@ -9,4 +31,3 @@ else
|
|||||||
export CN_REGION=1
|
export CN_REGION=1
|
||||||
echo "[INFO] Region switched to: 1 (国内)"
|
echo "[INFO] Region switched to: 1 (国内)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+26
-3
@@ -1,4 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# 链接 zshrc、安装 Oh My Zsh,并将默认 shell 设为 zsh
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$SCRIPT_DIR/common/help.sh"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
用法: zsh-init
|
||||||
|
|
||||||
|
1. 将 ~/.zshrc 链接到 ~/.dotfile/zsh/.zshrc
|
||||||
|
2. 若未安装则安装 Oh My Zsh(--unattended --keep-zshrc)
|
||||||
|
3. 将默认登录 shell 设为 zsh
|
||||||
|
|
||||||
|
选项:
|
||||||
|
-h, --help 显示此帮助
|
||||||
|
|
||||||
|
本机额外配置可写入 ~/.zshrc.local。
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
dotfile_help_requested "${1:-}" && dotfile_show_help
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
DOTFILE="${DOTFILE:-$HOME/.dotfile}"
|
DOTFILE="${DOTFILE:-$HOME/.dotfile}"
|
||||||
@@ -14,7 +37,7 @@ ln -sf "$ZSHRC_REPO" "$ZSHRC_HOME"
|
|||||||
echo " $ZSHRC_HOME -> $ZSHRC_REPO"
|
echo " $ZSHRC_HOME -> $ZSHRC_REPO"
|
||||||
|
|
||||||
if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
|
if [[ ! -d "$HOME/.oh-my-zsh" ]]; then
|
||||||
echo "安装 Oh My Zsh(--unattended:安装脚本内不改 shell、不自动进 zsh;--keep-zshrc:保留已链接的 .zshrc)…"
|
echo "安装 Oh My Zsh…"
|
||||||
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc
|
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc
|
||||||
else
|
else
|
||||||
echo "Oh My Zsh 已存在,跳过安装 (~/.oh-my-zsh)"
|
echo "Oh My Zsh 已存在,跳过安装 (~/.oh-my-zsh)"
|
||||||
@@ -35,5 +58,5 @@ fi
|
|||||||
chsh -s "$zshpath"
|
chsh -s "$zshpath"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "完成。当前仓库的 .zshrc 已启用 z 插件(Oh My Zsh plugins/z),默认 shell 已改为: $zshpath"
|
echo "完成。默认 shell 已改为: $zshpath"
|
||||||
echo "请重新登录或新开终端后生效。本机额外配置可写入 ~/.zshrc.local(不会被链接覆盖)。"
|
echo "请重新登录或新开终端后生效。"
|
||||||
|
|||||||
Reference in New Issue
Block a user