【问题标题】:running sudo command in bash script and running it with launchd在 bash 脚本中运行 sudo 命令并使用 launchd 运行它
【发布时间】:2023-04-28 08:59:02
【问题描述】:

我有一个 bash 脚本,我想在 OS X 上使用已启动的 plist 文件运行。我遇到的问题是 bash 脚本包含 sudo 命令并且它正在阻止它运行。例如,我的 bash 脚本如下所示:

#!/bin/bash
sudo /opt/local/bin/bindfs -u user1 /Library/WebServer/Documents/user1 /vhosts/user1/public_html
sudo /opt/local/bin/bindfs -u user2 /Library/WebServer/Documents/user2 /vhosts/user2/public_html

我的 com.test.bindfs.plist 文件看起来像这样(使用 Lingon 创建):

<?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>GroupName</key>
    <string>admin</string>
    <key>Label</key>
    <string>com.jamespayne.bindfs</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/bindfs.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

我通过在启动后运行脚本并输入密码来检查脚本是否有效,但它不会在启动时运行。 launchd plist 正在运行,但出现以下错误:

sudo:不存在 tty,也没有指定 askpass 程序

任何人都知道如何让这个工作或为什么我会得到这个错误。谢谢。

【问题讨论】:

    标签: macos bash launchd


    【解决方案1】:

    您可能只需将属性列表移动到 /Library/LaunchDaemons/ 并从脚本中删除 sudo 命令。

    请参阅man launchdman launchd.plistthis blog post

    【讨论】:

    • 虽然这是我最终所做的并且它解决了问题,但我将不得不接受 *foe 的回答,因为它专门解决并解释了与原始脚本相关的问题。无论如何,我对你的答案投了赞成票,因为它是一个相关的选择。
    【解决方案2】:

    如果您从 Google 来到这里,希望以 sudo/root 权限运行用户登录 LaunchAgent,您可以执行以下操作:

    • 如果为所有用户运行,则将 plist 放入 /Library/LaunchAgents,如果只为单个用户运行,则将 plist 放入 ~/Library/LaunchAgents
    • 让第一个 ProgramArguments 成为 sudo,剩下的就是您正在运行的命令
    • /etc/sudoers.d 文件中设置NOPASSWORD 配置,以允许launchctl 在没有交互式密码提示的情况下升级您的特定命令。

    请参阅this answer 了解更详细的分步演练。

    【讨论】:

      【解决方案3】:

      sudo 是一个交互式命令,要求用户输入密码才能继续。我想sudo 无法找到 tty,只会出现错误退出。

      你想要的命令是su,它是非交互式的,唯一的例外是你需要root才能运行它。但是,在您的情况下,您可能根本不需要它,因为脚本是由特权用户运行的?

      另外你为什么要把脚本放到/usr/bin?馊主意;请改用/usr/local/bin(或/usr/local/sbin,如果存在)。

      【讨论】:

      • 感谢您的安全提示。搬家了。