2015-04-28 26 views
2

在Linux上,可以运行readlink /proc/self/fd/0readlink /dev/fd/0以获取附加到stdin的任何文件或设备的名称。可能获得附加到OS X中的标准输入文件的名称?

这可能在Mac OS上?


要讲解使用情况 - 我有一个脚本行为大致类似于如下:

IFS= read -r -d '' stdin_content ||: 
for target; do 
    ssh "$target" "$command" < <(printf %s "$stdin_content") 
done 

这有明显的警告时,要读取的内容包含文字NUL值(可不会被存储在shell中的标量变量中),并且在输入文件内丢失位置信息;如果需要的话,我愿意忽略那些目前的情况,或者通过base64存储器对$stdin变量进行往返。

如果我能够检测到脚本的stdin来自常规文件并直接从该文件中的该文件重定向的情况将会很有帮助。 [ -f /dev/fd/0 ]实际上做正确的事情在Mac OS庆典,尽管/dev/fd/0不存在(的test内置知道该/dev/fd扩展的),但我在为检索其名称的手段损失。

+0

有趣的问题,但恕我直言,一个程序不能依靠那个。没有一个UNIX工具正在这样做(纠正我,如果我错了),这是使他们的灵活性的事情之一。 – hek2mgl

+0

@EtanReisner,是的,我知道NUL不能被处理,并且我在我的问题中明确地说了很多。 –

+0

@EtanReisner,同样,是的,我知道ssh并不是从文件中读取数据,但是如果我知道是否有文件,如果是的话文件*是*,我可以在可能的情况下让它做到这一点,当这些输入来自普通文件时,不适合内存的输入会被处理。这是我的目标。 (可能只是创建一个临时文件 - 也会修复NUL的情况 - 但这是一个不太有趣的问题)。 –

回答

4

您可以使用fcntl功能与(BSD和Mac OS特定的X)选项F_GETPATH

$ cat stdinname.c 
#include <stdio.h> 
#include <fcntl.h> 
int main() { 
    char path[80]; 
    fcntl(0, F_GETPATH, path); 
    printf("stdin is `%s`\n", path); 
} 
$ gcc stdinname.c 
$ ./a.out < stdinname.c 
stdin is `/Users/eduffy/junk/stdinname.c` 

代码应该包括一些错误检查..但它的要点是存在的。

编辑:错过bash部分。这似乎工作..不会像你一样的/proc/self/...方法:

lsof -p $$ | awk '{if($4=="0r"){print $9}}' 

编辑2:下面是输出由空字节的安全分析分离领域的一个版本。

lsof -p $$ -F fn0 | awk '-F\0' '{if($1=="f0"){print substr($2,2)}}' 
+1

有帮助!如果我要用C编译某些东西,我会试图将它作为一个可装入的模块用于bash解释器(直接分配给变量,而不是写入标准输出,并且需要让用户明确地读取内容 - 处理带有换行符和其他角落案例的文件名可能在shell中有点危险),但是如果在供应商打包的工具中没有本地可用的等价物,那么这非常有助于指向正确的方向。 –

+0

啊..我错过了这是一个bash脚本。 – eduffy

+0

请参阅编辑bash版本。 – eduffy

相关问题