如何在Xcode 4的“Run Script”构建阶段中使用sudo?

17

我需要在Xcode 4的“运行脚本”构建阶段中使用sudo执行一个命令。然而,编译器报错:

sudo: 没有tty并且没有指定askpass程序

有没有聪明的解决这个问题的方法?


我建议说明您使用sudo访问来做什么。这可能会打开更广泛的选择。 - Joshua Nozzi
将文件从一个位置复制到另一个位置,需要使用 root 访问权限完成。 - ericg
我有同样的问题,我已经为该脚本设置了ALL=NOPASSWD。实际上,如果我从控制台执行它,它不会要求密码。 - hithwen
7个回答

13

一个解决方案是将sudo密码放入一个可执行的shell脚本中,如下所示:

#!/bin/bash
echo thesudopassword

这个shell脚本可能被命名为password.sh。

然后,设置环境变量SUDO_ASKPASS=password.sh。

一旦这个设置完成,就可以将-A选项传递给sudo。这个选项使用ASKPASS程序来获取sudo密码。ASKPASS程序只需要将密码写入标准输出即可。

因此,例如:

sudo -A ditto -V /tmp/testserver.dst /

这显然是一个相当不安全的解决方案,但它确实起作用。


7

以下是两个尚未提出的想法,这两个想法可能比当前接受的答案更好/更安全:

第一种选择是将需要以root身份运行的脚本部分放入脚本文件(.sh或其他),然后将其设置为root setuid: chmod go-w,+sx scriptfilesudo chown root scriptfile。这意味着该脚本将自动以root身份运行,从而避免了您需要进行身份验证才能运行它(只需更改它)。只要其操作不受用户输入的影响,这应该是非常安全的。(当然,如果您编写一个脚本,该脚本需要输入参数并删除或运行它,或者对其执行任何其他操作,那么这将是不安全的。)

第二种选择是使用AppleScript(可能通过osascript)。 AppleScript允许您使用管理员权限运行shell脚本:do shell script "sudo command goes here" with administrator privileges,这将弹出一个图形对话框,要求输入密码。

这两个选项中的第一个选项适用于自动化环境,但可能无法很好地处理(例如)被检入SCM或发送给另一个用户的情况。第二个选项在这方面效果更好,但每次都需要输入密码,因此对于自动化构建脚本的效果不佳。


1
将uid设置为root是个好主意。我不太确定我喜欢applescript的答案。我最不想要的就是每次需要构建时都被要求输入密码。 - ericg
@ericgorr 确实如此,尽管人们希望通常不需要root权限来进行普通的构建(因为大多数测试应该能够在您的主目录中完成),但只有偶尔需要进行一次测试以确保安装在系统位置或类似位置时工作正常。 当然,我不知道你在这里做什么。 - arcticmac
在使用 chown 后,当我在 AppCode 中保存我的 shell 文件时,权限会被重置为我的用户。现在我正在使用 ASKPASS 方法。 - vaughan
在El Capitan中,例如,kextload不会加载内核扩展,除非它被chown为root:wheel,并且Xcode无法修改构建产品,除非它未被chown为root:wheel,因此需要在构建之前和之后都作为root运行脚本。 - user2975337
不幸的是,在El Capitan中无法工作(没有suid shell脚本)。如果它无法适应system("...")调用,可能可以从suid二进制文件启动脚本,但这可能无法保留Xcode环境变量。为此,路径限制的sudoers条目可以起作用,但比您的答案不太安全。 - user2975337

2
另一个解决这个问题的方法是修改sudoers文件并将您的帐户添加到其中,并说明永远不应要求输入sudo密码。实现这一点相当简单:
运行:
sudo visudo

在用户权限规范部分添加一行,类似于:
youraccountname ALL=(ALL) NOPASSWD: ALL

当然,这样做可能是危险的,所以要小心。在采取这种方法之前,我建议阅读sudoers和visudo的手册页面。


2
最好使用 youraccountname ALL=(ALL) NOPASSWD:SETENV: /path/to/script,这将限制无密码许可到该特定路径,然后在 Xcode 中使用 sudo -E /the/script 传输环境变量(例如 $BUILT_PRODUCTS_DIR 等)。 - user2975337

1

您可以直接以管理员身份运行以下命令(将 echo YourCommandHere > /tmp/hello 更改为您的命令):

osascript -e 'do shell script "sudo echo YourCommandHere > /tmp/hello " with administrator privileges'

在您的源目录中运行脚本,可以使用以下命令:

osascript -e 'do shell script "bash -x $SOURCE_ROOT/MyAdminScript.sh 1>/tmp/build-log 2>/tmp/build-log.err" with administrator privileges'

这将运行脚本并将其输出记录到 /tmp/build-log 和 /tmp/build-log.err。
有关脚本中有用的变量,请参见https://help.apple.com/xcode/mac/8.0/#/itcaec37c2a6

1

-1

你也可以通过从终端使用sudo将项目作为参数提供给XCode来执行它,像这样:

sudo /Developer/Applications/Xcode.app/Contents/MacOS/Xcode /path/to/your/project.xcodeproj

我能想到的最简单的解决方案,但可能存在一些缺点,因为您将以 root 身份执行 XCode。


2
哎呀。从技术上讲,这可以工作,但我建议不要这样做,特别是考虑到 Xcode 4 有多么容易崩溃(想象一下它在具有 root 权限的情况下可能造成的混乱)。 - Richard
1
这会给项目的未来变更带来麻烦,因为此后你将始终需要以 root 身份运行 Xcode。 - N_A

-4

不需要在任何地方写下你的sudo密码。只需打开终端窗口并输入

$ sudo echo "hello"

输入密码后,它会在一段时间内保持有效 - 不确定多长时间 - 并且由 Xcode 生成的 shell 将继承此权限。

如果您稍后再次收到“没有 tty 存在”的消息,请重复该过程


2
可以运行,但在自动化环境中没有用处。 - Jasarien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接