macos - 为什么不在此处传播 DYLD_LIBRARY_PATH?

标签 macos bash shell environment-variables

我有一个我正在尝试运行的简单 C++ 程序,它与我之前构建的 Boost.Thread 库版本相关联。我似乎无法理解运行时库路径在 OS X 上的行为方式。

因为我的 Boost 库没有 RPATH-relative install name ,我正在使用 DYLD_LIBRARY_PATH 环境变量告诉动态链接器在运行时在哪里可以找到 libboost_thread.dylib

如果我直接在我的 (bash) shell 中运行该程序,这会很好地工作:

[~/git/project]$ echo $DYLD_LIBRARY_PATH
/Users/jasonr/git/project/boost/lib
[~/git/project]$ .sconf_temp/conftest_7
[~/git/project]$ # Program runs successfully; this is what I expect.

但是,该程序作为我正在使用的类似于 autoconf 的框架进行的一系列测试的一部分运行。它使用 sh -c 在子 shell 中运行程序。如果我尝试这样做,会发生以下情况:

[~/git/project]$ # Make sure the environment variable is exported to child shells.
[~/git/project]$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH
[~/git/project]$ # Try to run it in a child shell.
[~/git/project]$ sh -c .sconf_temp/conftest_7
dyld: Library not loaded: libboost_thread.dylib
  Referenced from: /Users/jasonr/git/project/.sconf_temp/conftest_7
  Reason: image not found
Trace/BPT trap: 5

在这种情况下,就好像环境变量没有传播到 dyld 一样。为什么会出现这种情况?我更熟悉 Linux 上 LD_LIBRARY_PATH 的行为,(我认为)它应该适用于上面的示例。为了完成这项工作,我还需要做些什么吗?

最佳答案

据推测,您正在运行 El Capitan (OS X 10.11) 或更高版本。这是系统完整性保护的副作用。来自System Integrity Protection Guide: Runtime Protections文章:

When a process is started, the kernel checks to see whether the main executable is protected on disk or is signed with an special system entitlement. If either is true, then a flag is set to denote that it is protected against modification. …

… Any dynamic linker (dyld) environment variables, such as DYLD_LIBRARY_PATH, are purged when launching protected processes.

所有系统提供的解释器,包括/bin/sh,都以这种方式受到保护。因此,当您调用 sh 时,所有 DYLD_* 环境变量都会被清除。

您可以编写一个 shell 脚本来设置 DYLD_LIBRARY_PATH,然后执行 .sconf_temp/conftest_7。您可以使用 shell 解释器来执行它——实际上,您必须这样做——并且环境变量会很好,因为清除发生在 protected 可执行文件启动时。基本上,这种方法类似于您问题中的工作示例,但封装在 shell 脚本中。

关于macos - 为什么不在此处传播 DYLD_LIBRARY_PATH?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35568122/

相关文章:

linux - cronjob等待理解

swift - Cocoa - PDFView/ThumbnailView 拖动

macos - 增加ulimit Macos 10.8

android - 在 MAC 操作系统上找不到 Android SDK 管理器设置

shell - 如何捕获 shell 管道中的错误代码?

shell - 如何将 'ls' 输出文件移动到 unix 中的文件夹

macos - 如何在 mac 优胜美地上撤消 `brew link --force openssl`

linux - 如何在 Bash 命令行中生成 ASCII 代码 2 和 3?

bash - 如何在脚本继续执行其他命令时使 osascript 显示对话框

linux - 如果只能执行 Windows 批处理脚本,为什么 bash 脚本需要执行位?