一键脚本
下面的脚本会安装 dufs、生成 launchd 配置、加载 WebDAV 服务,并打包出一个可点击启动的 WebDAV.app。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
| #!/bin/zsh
set -eu
SHARE_DIR="$HOME/Documents/PT" # 需要共享的目录,改成实际路径
PORT="9999" # WebDAV 监听端口
APP_NAME="WebDAV" # 打包后显示的应用名称
LABEL="com.anthony.dufs.webdav" # launchd 服务标识,通常保持不变
BASE_DIR="$HOME/Library/Application Support/dufs-webdav" # 运行脚本保存目录
SCRIPT_PATH="$BASE_DIR/start-dufs-webdav.sh" # dufs 启动脚本
PLIST_PATH="$HOME/Library/LaunchAgents/${LABEL}.plist" # launchd 配置文件
LOG_DIR="$HOME/Library/Logs/dufs-webdav" # 服务日志目录
APP_SCRIPT="$HOME/Desktop/webdav-launcher.applescript" # 原始启动器脚本
APP_PATH="/Applications/${APP_NAME}.app"
if ! command -v brew >/dev/null 2>&1; then
echo "Homebrew 未安装"
exit 1
fi
if ! command -v dufs >/dev/null 2>&1; then
brew install dufs
fi
DUFS_BIN="$(command -v dufs)"
mkdir -p "$SHARE_DIR" "$BASE_DIR" "$HOME/Library/LaunchAgents" "$LOG_DIR"
cat > "$SCRIPT_PATH" <<EOF
#!/bin/zsh
set -eu
SHARE_DIR="$SHARE_DIR"
PORT="$PORT"
exec "$DUFS_BIN" "\$SHARE_DIR" \\
--bind 0.0.0.0 \\
--port "\$PORT" \\
--hidden ".*" \\
--allow-all
EOF
chmod +x "$SCRIPT_PATH"
cat > "$PLIST_PATH" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>$LABEL</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>$SCRIPT_PATH</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>$SHARE_DIR</string>
<key>StandardOutPath</key>
<string>$LOG_DIR/stdout.log</string>
<key>StandardErrorPath</key>
<string>$LOG_DIR/stderr.log</string>
</dict>
</plist>
EOF
plutil -lint "$PLIST_PATH"
cat > "$APP_SCRIPT" <<EOF
on run
set uid_text to do shell script "id -u"
set agent_plist to "$PLIST_PATH"
set agent_label to "gui/" & uid_text & "/$LABEL"
set shell_cmd to "/bin/sh -lc " & quoted form of ("launchctl bootstrap gui/" & uid_text & " " & quoted form of agent_plist & " >/dev/null 2>&1 || true; for i in 1 2 3 4 5; do launchctl kickstart -k " & quoted form of agent_label & " >/dev/null 2>&1 && exit 0; sleep 1; launchctl bootstrap gui/" & uid_text & " " & quoted form of agent_plist & " >/dev/null 2>&1 || true; done; exit 1")
do shell script shell_cmd
open location "http://127.0.0.1:$PORT/"
end run
EOF
osacompile -o "$APP_PATH" "$APP_SCRIPT"
launchctl bootout gui/$(id -u)/$LABEL >/dev/null 2>&1 || true
sleep 1
launchctl bootstrap gui/$(id -u) "$PLIST_PATH"
sleep 1
launchctl kickstart -k gui/$(id -u)/$LABEL
echo "服务地址: http://127.0.0.1:${PORT}/"
echo "已生成: $APP_PATH"
|
前提
这套配置会将 SHARE_DIR 目录以匿名可写方式共享到局域网,适合可信内网环境。默认端口为 9999。
变量说明
SHARE_DIR 决定实际共享目录。需要更换共享位置时,只需要修改这一个变量。
PORT 决定 WebDAV 监听端口。局域网访问地址和本机访问地址都会随这个端口变化。
APP_NAME 和 APP_PATH 控制打包后 .app 的显示名称。需要将 PT WebDAV 改为 WebDAV 这类变化时,直接修改这里即可。
APP_SCRIPT 是原始 AppleScript 文件,APP_PATH 是打包产物。后续若只重建桌面启动器,直接重新编译这两个路径即可。
LABEL 是 launchd 服务标识。没有同时维护多个实例的需求时,保持固定最简单。
脚本做了什么
脚本首先确保 dufs 已安装,并解析当前系统中的实际二进制路径。这样可以同时兼容 Apple Silicon 和 Intel Mac 上不同的 Homebrew 安装位置。
随后会生成一个独立的 dufs 启动脚本,并把共享目录、端口等运行参数集中写入其中。真正的后台服务由 launchd 读取这个脚本来启动。
接着会生成 LaunchAgent plist,把服务注册为当前用户会话中的常驻后台任务,并将日志输出到 ~/Library/Logs/dufs-webdav。
最后会生成一个 AppleScript 启动器,并通过 osacompile 打包成 .app。这个启动器会先尝试拉起后台服务,再自动打开 http://127.0.0.1:$PORT/。当前打包结果仍使用默认 applet 图标,本文仅覆盖功能性封装。
访问与验证
本机访问地址:
局域网其他设备访问地址:
1
| http://<Mac 的局域网 IP>:9999/
|
端口监听状态可以直接检查:
1
2
| lsof -nP -iTCP:9999 -sTCP:LISTEN
curl -I http://127.0.0.1:9999/
|
Finder 的“连接服务器”也可以直接填写相同地址。
常见维护
共享目录、端口或 .app 名称发生变化时,直接修改脚本开头的 SHARE_DIR、PORT、APP_NAME,然后重新执行整段脚本即可。打包后的 .app 不需要单独维护内部配置。
如果只需要重新加载后台服务,可执行:
1
2
3
4
5
| launchctl bootout gui/$(id -u)/com.anthony.dufs.webdav >/dev/null 2>&1 || true
sleep 1
launchctl bootstrap gui/$(id -u) "$HOME/Library/LaunchAgents/com.anthony.dufs.webdav.plist"
sleep 1
launchctl kickstart -k gui/$(id -u)/com.anthony.dufs.webdav
|
如果只需要重建桌面启动器,可执行:
1
2
| APP_NAME="WebDAV"
osacompile -o "/Applications/${APP_NAME}.app" "$HOME/Desktop/webdav-launcher.applescript"
|
日志位置如下:
1
2
| tail -f "$HOME/Library/Logs/dufs-webdav/stdout.log"
tail -f "$HOME/Library/Logs/dufs-webdav/stderr.log"
|