You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免sudo执行Swift文件回收代码时文件进入root回收站?

解决sudo执行时文件移入root回收站的问题

好问题!要避免sudo运行脚本时文件被移入root的回收站,同时又不硬编码用户回收站路径、也不提前降低权限,核心思路是在执行回收站操作前,临时切换回调用sudo的原用户身份——毕竟macOS的trashItemAPI会自动对应当前用户的回收站,只要身份是原用户,就会正确放入对应的位置。

下面是修改后的脚本,关键是利用sudo环境下的SUDO_UID和SUDO_GID环境变量来切换身份:

#!/usr/bin/swift
import Darwin

struct swifterr: TextOutputStream {
    public static var stream = swifterr()
    mutating func write(_ string: String) {
        fputs(string, stderr)
    }
}

// 处理sudo下的身份切换
if let sudoUidStr = ProcessInfo.processInfo.environment["SUDO_UID"],
   let sudoGidStr = ProcessInfo.processInfo.environment["SUDO_GID"],
   let sudoUid = uid_t(sudoUidStr),
   let sudoGid = gid_t(sudoGidStr) {
    // 先切换组ID,再切换用户ID(posix要求的顺序)
    if posix_setgid(sudoGid) != 0 {
        print("Failed to switch to original group ID: \(strerror(errno))", to: &swifterr.stream)
        exit(1)
    }
    if posix_setuid(sudoUid) != 0 {
        print("Failed to switch to original user ID: \(strerror(errno))", to: &swifterr.stream)
        exit(1)
    }
}

if CommandLine.arguments.count < 2 {
    print("Usage: \(CommandLine.arguments[0]) <file1> [file2...]", to: &swifterr.stream)
    exit(2)
}

let manager: FileManager = FileManager.default

for item in CommandLine.arguments[1...] {
    do {
        let path: URL = URL(fileURLWithPath: item)
        var destination: NSURL?
        try manager.trashItem(at: path, resultingItemURL: &destination)
    } catch {
        print("Failed to trash \(item): \(error.localizedDescription)", to: &swifterr.stream)
        exit(1)
    }
}

exit(0)

关键说明:

  • 身份切换逻辑:当脚本通过sudo运行时,系统会自动设置SUDO_UID和SUDO_GID环境变量,分别对应调用sudo的原用户的UID和GID。我们通过这两个值切换回原用户身份,再执行trashItem操作。
  • 切换顺序:必须先调用posix_setgid切换组ID,再调用posix_setuid切换用户ID——因为一旦切换到普通用户身份,就可能没有权限修改组ID了。
  • 兼容性:这个方法完全依赖系统原生的环境变量和posix接口,不需要硬编码任何路径,也不需要额外依赖工具,符合你的需求。

测试一下:用sudo运行这个脚本删除文件,文件会出现在你自己的回收站里,而不是root的回收站;普通用户直接运行也完全正常。

内容的提问来源于stack exchange,提问作者amyspark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:06:01