运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?
Posted
技术标签:
【中文标题】运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?【英文标题】:Can you redirect log output of Xcode console to Terminal when running iPhone Simulator? 【发布时间】:2009-12-15 20:30:06 【问题描述】:我不喜欢在模拟器中(或在设备上)调试 iPhone 应用程序时使用 Xcode 的控制台输出窗口。我希望能够使用 Unix 工具箱并使用 grep 过滤日志输出。但要做到这一点,我需要让 Xcode 将正在运行的 iPhone 应用程序的日志输出发送到终端。
有没有办法做到这一点?
【问题讨论】:
好问题。直到此刻,这才让我感到困扰。 我找到了自己问题的答案。它在cocoadev.com/index.pl?NSLogToFile 和开头的评论中“更好的是,避免潜在溢出的 C 数组并使用 Cocoa goodness...” 感谢丹的链接。我认为这是真正的答案。 【参考方案1】:不能说它在模拟器中是如何工作的,但是重定向标准输出并不是很困难。假设您想将其通过管道传输到您自己的视图中:
#include <unistd.h>
stderr->_write = RedirectOutputToView;
stdout->_write = RedirectOutputToView;
并使用原型:
int RedirectOutputToView(void *inFD, const char *buffer, int size);
【讨论】:
我知道如何重定向标准输出。我只需要知道如何让 iPhone 应用程序在 XCode 中以调试模式运行以输出到终端的标准输出。 谢谢,但必须有更简单的方法来做到这一点。例如,如果有一种方法(我不知道)可以直接从终端在 iPhoneSimulator 中启动 iPhone 应用程序,那么日志输出可能会出现在您启动应用程序的终端窗口中。 因此将其重定向到一个文件并在其上运行 tail -f 。如果终端有一个标准输出,你不能从它的地址空间之外写入它。 如果 XCode 将其控制台日志输出写入某处的文件中,很高兴知道这样我们就可以直接使用 tail -f 了。 啊哈,我搞定了。解决方案类似于 NSString *logPath = @"/path/to/log/file.log"; freopen([logPath fileSystemRepresentation], "a", stderr);在 main() 函数中【参考方案2】:在 XCode 6 中,日志在此处被截取:/Users/<username>/Library/Logs/CoreSimulator/<app guid>/system.log
。 username 当然是你的系统用户名,app guid 是 XCode 为模拟器生成的东西。
确定 app guid 是什么的最简单方法是为模拟器构建应用并查看上次更改的目录:
~ ❯❯❯ cd ~/Library/Logs/CoreSimulator
~/L/L/CoreSimulator ❯❯❯ ls -latr
total 64
-rw-r--r-- 1 x staff 519 27 Aug 21:54 ios Simulator.log
drwxr-xr-x 13 x staff 442 27 Aug 21:54 D283605A-0BA9-43B3-AB6B-F4858BE6E45E
drwxr-xr-x 15 x staff 510 8 Oct 03:56 425D8E41-0842-4F2D-BC22-8C3695E350EF
显然 425D8E41-0842-4F2D-BC22-8C3695E350EF 是最后修改的目录,所以现在您可以对实时日志执行 tail -f ~/Library/Logs/CoreSimulator/425D8E41-0842-4F2D-BC22-8C3695E350EF/system.log | grep keyword
或其他任何您可能想要执行的操作。
【讨论】:
最佳答案。顺便说一句,XCode 7 也是如此【参考方案3】:我发现 this answer 可以很好地满足我的目的,尽管它需要运行模拟器才能在终端中实时流式传输:
我删除了模拟器检查并在重定向之前添加了一个 NSLog 语句,以便 XCode 控制台吐出文件的位置:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
NSLog(@"redirecting STDERR: %@", logPath);
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
我认为最强大的解决方案是使用日志库(例如CocoaLumberjack )并使用您喜欢的任何目的地对其进行配置。
【讨论】:
【参考方案4】:我可以在终端中获取设备输出,但无法同时在 xcode 中连接调试会话(我猜是因为终端有调试连接)。
使用 idevicedebug 从终端启动应用程序。
idevicedebug -u <device uuid> run com.myco.apps.myapp
其中 com.myco.apps.myapp 是捆绑包 ID,可以在设备窗口的“已安装应用”窗格中看到。
我认为 idevicedebug 是用 ideviceinstaller 安装的,可以用 brew 完成
brew install ideviceinstaller
但我建议搜索 ideviceinstaller 和 libimobiledevice (它使用的库)只是为了确定。
这是一个小烦恼,但我发现在终端中获取程序输出的最佳方式。
【讨论】:
【参考方案5】:为什么不使用Console.app
?一种查看和 grep 日志的好方法,而不是 xCode 的调试窗口或终端。默认情况下,这是 macOS 的一部分。
如果你有 C printf 语句,那么下面的 SO 有很多有用的信息: Get printf on Console.app
【讨论】:
【参考方案6】:在 Xcode 6 中它已经这样做了。打开与您当前使用的模拟器构建关联的 System.log 文件。对我来说,它在这里:/Users/josh.lang/Library/Logs/CoreSimulator/3BB4CBFB-5A67-4E93-91B5-78E6E3658A16/system.log
它会保留所有内容,但我注意到如果我在运行我的 sim 时打开它,它也会自行重新加载。
【讨论】:
以上是关于运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 xcode 4.6.2 中使用 iphone 模拟器 5.1
Xcode 8.2.1 中的 iPhone 模拟器运行速度有点慢 [关闭]