【问题标题】:Applescript Execute Shell with Input and Admin PrivilegesApplescript 使用输入和管理员权限执行 Shell
【发布时间】:2014-05-28 07:55:24
【问题描述】:

我正在尝试编写一个自动化服务来在终端中启动virtualhost.sh

使用服务上下文菜单打开对话框询问虚拟主机的名称,然后运行一个applescript来启动终端并传入输入文本。

我想要的是将我的用户名和密码传递给管理员权限,这样我就不需要在终端中使用 sudo 传递它。

这可以通过do shell script 完成,但执行bin/sh 并且virtualhost.sh 是一个bash 脚本,所以我收到错误bin/sh: virtualhost.sh command not found

我也可以使用do script with command,但这不允许我传递用户名和密码。

我的代码如下所示:

on run {input, parameters}
    set vhost to "virtualhost.sh " & input
    tell application "Terminal"
        activate
        do shell script vhost user name "user" password "pass" with 
                  administrator privileges

    end tell
end run

这会产生前面提到的 bin/sh 错误。

do script with command

on run {input, parameters}
    set vhost to "virtualhost.sh " & input
    tell application "Terminal"
        activate
        do script with command vhost user name "user" password "pass" with
                  administrator privileges

    end tell
end run

这会产生转义错误:预期行尾等,但找到了属性。

有没有办法正确地做到这一点?

【问题讨论】:

  • 听起来您正在尝试提供服务。有理由不使用launchd吗?

标签: bash shell applescript


【解决方案1】:

不是特别熟悉 AppleScript Studio,但如果您提供 virtualhost.sh 的完整路径,则可以使用普通的旧 AppleScript(似乎有同样的问题)来完成。 (此外,“do shell script”不需要终端。)示例:

set vhost to "/usr/local/bin/virtualhost.sh " & input
do shell script vhost user name "user" password "pass" ¬
    with administrator privileges

您还可以扩展 $PATH(默认为 /usr/bin:/bin:/usr/sbin:/sbin 并带有“do shell script”)以包含 virtualhost.sh 的路径,例如:

set vhost to "{ PATH=$PATH:/usr/local/bin; virtualhost.sh " & input & "; }"
do shell script vhost user name "user" password "pass" ¬
    with administrator privileges

如果你想要一个相对路径,你可以将 virtualhost.sh 放在脚本应用程序或包中(例如在 Contents/Resources 中),可以在终端中或通过控制单击并选择“显示包内容”。然后使用“我的路径”:

set vhostPath to "'" & POSIX path of (path to me) & ¬
    "/Contents/Resources/virtualhost.sh" & "'"
set vhost to vhostPath & space & input
do shell script vhost user name "user" password "pass" ¬
    with administrator privileges

【讨论】:

  • 我在 vhost 变量中设置了脚本的完整路径,它确实以这种方式工作,但 .sh 脚本实际上会询问几个问题,这些问题会自动设置为它们的默认值,这并不理想。所以我想我会选择do script with command 并继续输入密码。这似乎是我可以使用 .sh 脚本中生成的提示的唯一方法。感谢您的帮助:)
  • 我想知道......如果我将此脚本粘贴到自动机运行 Shell 脚本对话框中,它会通过问题吗?
  • 好的,我明白了——您需要终端提示的交互性,但希望避免用户必须输入他们的密码,这只能通过“do shell script”获得。一个公平的工作想法是调整 virtualhost.sh 以接受参数作为提示的替代方法,然后使用“显示对话框”在“执行 shell 脚本”之前进行提示,提供所有答案作为一系列论据。但是,我查看了 virtualhost.sh,由于许多提示是在它检查之后出现的,这可能需要大量的返工。我将看看我是否可以想出另一种方法。
  • Posted alternate approach 以 root 用户身份打开终端,因此您可以使用管理员访问权限运行交互式 shell 脚本,而无需密码,无论这实际上是否是个好主意。
  • @VinceKronlein 嗯嗯。感谢您接受我的回答;希望它对其他人仍然有用!
【解决方案2】:

根据my other answer 上的评论,我发布次要答案的精神是有意愿,有办法,但这是一种不同的、更危险的方法。但是,这是我能想到的针对这一特殊要求的唯一解决方案(获得终端的交互性,但在以管理员身份运行脚本时无需提示输入管理员密码)。

此解决方案以 root 身份运行终端,do shell script "command" with administrator privileges 就是这样做的。这很危险,因为您有一个具有 root 访问权限的打开终端窗口,因此请仔细权衡好处与潜在后果,例如打开一个新终端窗口并以 root 身份在 Bash 提示符下。

因此,打开的终端实例在脚本完成后被杀死;如果删除了“kill”命令,请注意您将获得多个终端实例,而不是同一实例中的多个窗口。

不知道这是否适用于 AppleScript Studio(它适用于 AppleScript 编辑器),但我想不出任何原因。

set input to "some_input"
set vhost to "/usr/local/bin/virtualhost.sh " & input
set kill to ¬
    "terminal_pid=$(</tmp/terminal_pid); rm /tmp/terminal_pid; kill $terminal_pid"

-- launch Terminal as root, and save its process ID in /tmp/terminal_pid
tell application "Finder" to set beforeProcesses to processes
do shell script ¬
    "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal " & ¬
    "&> /dev/null & echo $! > /tmp/terminal_pid" user name "user" password ¬
    "pass" with administrator privileges

-- wait until the new Terminal is confirmed to be running
tell application "Finder"
    repeat while (processes is equal to beforeProcesses)
        do shell script "sleep 0.5"
    end repeat
end tell

-- Perform script in root Terminal window that we just opened,
-- and kill Terminal when done to prevent open root prompt
-- and multiple processes.
tell application "Terminal"
    activate
    do script vhost & "; " & kill
end tell

-- optional: wait until Terminal is gone before continuing
do shell script "while [[ ( -f /tmp/terminal_pid ) " & ¬
    "&& ( \"$(ps -p $(</tmp/terminal_pid) -o%cpu='')\" ) ]]; do sleep 0.5; done"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多