我有一个用Xcode 7编写的c代码,并在运行El Capitain(OSX 10.11.6)的Mac笔记本电脑上运行。该程序使用以下代码行调用另一个程序“bertini”:
eflag = execvp("bertini", "input");
或者
system("bertini input");
在升级我的操作系统之前,这两个工作都很好(我运行Xcode 3或4,我不记得。)现在程序不再有效,因为它无法找到程序bertini。
我发现问题是bertini不在搜索路径上,因为在El Capitain中,我不允许将可执行文件复制到/ usr / bin /。因此,请按照此页面上的说明操作: http://forums.appleinsider.com/discussion/189702/cant-copy-file-to-usr-bin-even-when-logged-in-as-root,
我将bertini可执行文件移动到我选择的文件夹中,并将~/.bash_profile
更改为指向此文件夹。现在bertini在终端上运行得很好,但是当我的程序调用它时。
在Xcode中运行时,我怎样才能编程来查找bertini的当前位置?我已经尝试输入完整目录(/ path / to / directory / containing / bertini / bertini),但这仍然无效。我也尝试过以前版本的Xcode的指令(例如在这个问题where is $PATH set in xcode?中),但似乎Xcode的版本非常不同,我不明白如何调整这些指令。此外,关于设置~/.MacOSX/environment.plist
的响应中的链接已断开,我对以“。”开头更改文件感到紧张。我不知道自己在做什么(我对此并不了解)。
请注意,这是用于学术研究,而不是一般用途,所以如果我只能在我的机器上工作(好吧,两台机器),那很好。
答案 0 :(得分:0)
我首先要说的是,使用execvp的代码示例看起来不正确,实际上不应该编译。你的意思可能是
char *const argvector[] = { (char *const)"bertini", (char *const)"input", NULL };
eflag = execvp("bertini", argvector);
或
eflag = execlp("bertini", "bertini", "input", (char *)0);
好的,现在开始解决你的问题了。至少有两种基本方法可以简单地使事情发挥作用。一种是指定在exec调用中将“bertini”放在何处的完整路径,如下例中使用execvp:
char *const argvector[] = { (char *const)"bertini", (char *const)"input", NULL };
eflag = execvp("/full/path/to/bertini", argvector);
exec函数的man手册页(man 3 exec)指定仅当作为“file”参数传入的字符串中没有任何“/”字符时才搜索路径。因此,如果它存在于指定的完整路径,则上述忽略路径并启动“bertini”。这可能是最简单的前进方式,它也适用于旧版本的MacOS。
但是如果由于某种原因你更愿意使用搜索路径,你可以确保从Finder启动的应用程序的路径使用launchctl shell命令使用特定的搜索路径,如下文所述 -
Environment variables in Mac OS X
只需输入命令
即可launchctl setenv PATH $PATH
>在〜/ .bash_profile中,在您更新路径以包含“bertini”的新位置然后(这很重要)之后,您需要重置Finder以吸收这些新信息。我认为退出并再次登录将会这样做,但如果我错了,请尝试重新启动。现在,从命令行启动的所有应用程序都将使用您更新的路径,原始的“系统”调用应该可以正常工作。
只是一个离别的评论。 / usr / local / bin是一个把东西放在后来的MacOS版本上的好地方(那些不允许更改/ usr / bin的版本)。它甚至可能位于Finder启动的应用程序使用的默认路径上。还有一件事要尝试。