The repo was committed from WSL with core.filemode=false, so the exec bit was never recorded. After actions/checkout the entry script comes down as 100644 and tests/test_cli.sh fails with Permission denied. Set mode 100755 on every script that is invoked directly (entry, installer, test suite, mock binaries). Sourced helpers under lib/ keep 100644 per convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86 lines
2.0 KiB
Bash
Executable File
86 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
|
SOURCE_SCRIPT="${SCRIPT_DIR}/iptables-forward.sh"
|
|
TARGET_BIN=${INSTALL_TARGET:-/usr/local/bin/iptables-forward}
|
|
|
|
usage() {
|
|
cat <<USAGE
|
|
用法:
|
|
sudo ./install.sh
|
|
sudo ./install.sh --uninstall
|
|
|
|
说明:
|
|
- 仅创建符号链接,不复制源码。
|
|
- 默认链接到 /usr/local/bin/iptables-forward。
|
|
- 可通过 INSTALL_TARGET 自定义目标路径。
|
|
USAGE
|
|
}
|
|
|
|
require_root() {
|
|
if (( EUID != 0 )); then
|
|
printf '请使用 root 或 sudo 执行安装脚本。\n' >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
target_is_current_link() {
|
|
[[ -L ${TARGET_BIN} ]] || return 1
|
|
[[ $(readlink -- "${TARGET_BIN}") == "${SOURCE_SCRIPT}" ]]
|
|
}
|
|
|
|
install_link() {
|
|
[[ -f ${SOURCE_SCRIPT} ]] || {
|
|
printf '未找到入口脚本: %s\n' "${SOURCE_SCRIPT}" >&2
|
|
exit 1
|
|
}
|
|
mkdir -p "$(dirname -- "${TARGET_BIN}")"
|
|
if [[ -e ${TARGET_BIN} || -L ${TARGET_BIN} ]]; then
|
|
if target_is_current_link; then
|
|
chmod 755 "${SOURCE_SCRIPT}"
|
|
printf '链接已存在: %s -> %s\n' "${TARGET_BIN}" "${SOURCE_SCRIPT}"
|
|
return 0
|
|
fi
|
|
printf '目标已存在且不是当前脚本的链接,拒绝覆盖: %s\n' "${TARGET_BIN}" >&2
|
|
exit 1
|
|
fi
|
|
ln -s "${SOURCE_SCRIPT}" "${TARGET_BIN}"
|
|
chmod 755 "${SOURCE_SCRIPT}"
|
|
printf '已创建链接: %s -> %s\n' "${TARGET_BIN}" "${SOURCE_SCRIPT}"
|
|
}
|
|
|
|
uninstall_link() {
|
|
if target_is_current_link; then
|
|
rm -f "${TARGET_BIN}"
|
|
printf '已删除链接: %s\n' "${TARGET_BIN}"
|
|
elif [[ -L ${TARGET_BIN} || -e ${TARGET_BIN} ]]; then
|
|
printf '目标不是当前脚本创建的链接,拒绝删除: %s\n' "${TARGET_BIN}" >&2
|
|
exit 1
|
|
else
|
|
printf '未发现已安装链接: %s\n' "${TARGET_BIN}"
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
case ${1:-install} in
|
|
--help|-h)
|
|
usage
|
|
;;
|
|
install)
|
|
require_root
|
|
install_link
|
|
;;
|
|
--uninstall|uninstall)
|
|
require_root
|
|
uninstall_link
|
|
;;
|
|
*)
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|