对于命令,如果-用作参数代替文件名将意味着 STDIN 或 STDOUT。
但在这个例子中,它创建了一个名为 的文件-:
echo hello > -
Run Code Online (Sandbox Code Playgroud)
我怎样才能-在这个例子中表示 STDOUT?
相反,我怎么能在示例中-命名一个文件-,例如:
cat -
Run Code Online (Sandbox Code Playgroud)假设一个程序cook接受一个参数:包含要烹饪的食物配方的文本文件的路径名。假设我想从bash脚本中调用这个程序,还假设我已经在一个字符串变量中拥有了配方:
#!/bin/bash
the_recipe="$(cat << EOF
wash cucumbers
wash knife
slice cucumbers
EOF
)"
cook ... # What should I do here? It expects a file, but I only have a string.
Run Code Online (Sandbox Code Playgroud)
当需要文件名参数时,如何将配方传递给命令?
我想创建一个临时文件只是为了传递文件,但我想知道是否有其他方法可以解决这个问题。
我一直想知道这一点,但从来没有花时间去了解,所以我现在就这样做 -此处显示的/proc/$$/fd/$N或的用法有多便携/dev/fd/$N?我理解POSIX 保证 /dev/null, /dev/tty, and /dev/console (尽管我前几天在阅读了这个答案的评论后才发现这一点)但是其他的呢?
据我所知,它们很常见,但我不能指望在哪些系统中找到它们?为什么不?找到一个比另一个更有可能吗?他们会总是表现出类似的属性吗?
我倾向于以各种方式广泛使用这些设备,我想知道是否有机会尝试一下。
此外,上述问题应该被理解为只是我想我想知道的,但是,因为我显然首先要问,所以我在这方面可能不是最了解的,它们不应该被视为严格的要求一个答案。如果可以,请告诉我。
我给了一个问题的答案,并评论它,让我阅读的基本定义的POSIX一致性部分弄清楚是否/dev/stdin,/dev/stdout而/dev/stderr实际上需要符合POSIX标准。
事实证明他们不是:
系统可能提供非标准扩展。这些是 POSIX.1-2008 不需要的功能,可能包括但不限于: [...] 具有特殊属性的附加字符特殊文件(例如
/dev/stdin,/dev/stdout、 和/dev/stderr)
据我所知,这是标准中唯一提到这些文件的地方。
我只能访问一个没有实现它们的“系统”(环境,真的),那就是 Windows 上的 MinGW(/dev就我所见,根本没有)。据我所知,所有免费的 Unices 都有,Cygwin、Windows 的新 Linux 环境和 Darwin/macOS 也有。
不过,我对商业 Unices 并不熟悉。
是否有一个 POSIX 系统、Unix 或某种描述的类 Unix 环境,今天还活着,它没有实现/dev/stdin, /dev/stdout, 和/dev/stderr作为文件系统中的文件?
在脚本中,错误通常用 发送到文件描述符 2 &2,即:
echo "error" >&2
Run Code Online (Sandbox Code Playgroud)
有时/dev/stderr改为使用:
echo "error" > /dev/stderr
Run Code Online (Sandbox Code Playgroud)
看着/dev/stderr,我看到它只是到 的符号链接/proc/self/fd/2,而后者又是到/dev/pts/5(在我当前的终端上)的符号链接。
看起来有点过于复杂了。这背后有什么逻辑吗?
使用/dev/stderr和&2等效吗?
其中任何一个都比另一个更受欢迎吗?
我正在处理一些rc.local在启动时运行的脚本,我注意到输出重定向的工作方式很奇怪。
如果我写了类似的东西echo "foo" >&1,它最终会出现在系统日志中,一切都很好。
但是当我写echo "foo" >>/dev/stdout, or 时echo "foo" >>/proc/self/fd/1,我收到一个错误,说没有这样的设备或地址。
进一步调查显示,这/proc/self/fd/1实际上是一个套接字。ls -l /proc/self/fd在rc.local印刷品中包括以下内容:
lr-x------. 1 root root 64 Jul 14 05:28 0 -> /dev/null
lrwx------. 1 root root 64 Jul 14 05:28 1 -> socket:[18485]
lrwx------. 1 root root 64 Jul 14 05:28 2 -> socket:[18485]
lr-x------. 1 root root 64 Jul 14 05:28 255 -> /etc/rc.d/rc.local
Run Code Online (Sandbox Code Playgroud)
所描述的行为可以很容易地重现nc。首先,找出哪个文件描述符绑定到套接字。您可以通过nc -l -p 25566 -c …
如果我的程序崩溃,我想避免放置临时文件。
UNIX 的美妙之处在于您可以保持文件打开 - 即使在您删除它之后也是如此。
因此,如果您打开文件,立即将其删除,然后进行缓慢处理,那么即使您的程序崩溃,用户也不必清理文件的可能性很高。
在 shell 中,我经常看到类似的东西:
generate-the-file -o the-file
[...loads of other stuff that may use stdout or not...]
do_slow_processing < the-file
rm the-file
Run Code Online (Sandbox Code Playgroud)
但是如果程序崩溃之前rm用户将不得不清理the-file。
在 Perl 中,您可以执行以下操作:
open(my $filehandle, "<", "the-file") || die;
unlink("the-file");
while(<$filehandle>) {
# Do slow processing stuff here
print;
}
close $filehandle;
Run Code Online (Sandbox Code Playgroud)
然后文件一打开就被删除。
shell 中是否有类似的结构?
bash ×2
portability ×2
shell-script ×2
stderr ×2
command-line ×1
open-files ×1
posix ×1
proc ×1
process ×1
shell ×1
socket ×1
stdin ×1
stdout ×1
utilities ×1