如何检查 stdin 是来自终端还是 shell 脚本中的管道?
我正在编写一个 POSIX shell 脚本,它可能会也可能不会从 stdin 接收输入,如 foo.sh
foo.sh
foo.sh
foo.sh
foo.sh
foo.sh
foo.sh < test.txt
,非交互方式。
如何检查标准输入上是否有任何内容,以避免在读取 -r 行...时暂停 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我的问题答对了,您可以尝试以下操作:
If I get the question right, you may try the following:
从字面上回答这个问题(但不是你真正想要的):
read -t 0
超时,零秒。
-t 5
但在抖动系统上即使这样也是有问题的。read -t
在 SUSv3 中未标准化。它位于 BSD sh、bash、zsh 中。它不是用 ksh 或 dash 表示的。所以你不能只使用 #!/bin/sh 并期望得到这个。
基本问题是,即使现在标准输入上没有任何内容,也不意味着很快就会有。调用程序通常会使标准输入连接到终端/其他设备,因此无法知道需要什么。
因此,要从字面上回答您的问题,您可以这样做,但实际上您的选择是:
[ -t 0 ]
To answer the question literally (but not what you actually want):
read -t 0
Timeout, zero seconds.
-t 5
but on a thrashing system even that is problematic.read -t
is not standardised in SUSv3. It is in BSD sh, bash, zsh. It's not in ksh or dash.So you can't just use #!/bin/sh and expect to have this.
The basic problem is that even if there's nothing on stdin now, that doesn't mean there won't be soon. Invoking a program normally leaves stdin connected to the terminal/whatever, so there's no way to tell what's needed.
So, to answer your question literally, you can do it, but in practice your options are:
[ -t 0 ]
您可以轻松实现与“cat”命令类似的行为,即从提供的文件列表中读取,或者如果未提供它们,则从标准输入中读取。
尽管您可能不会使用这个想法,但我认为这篇 Linux Journal 文章对您来说会很有趣 http://www.linuxjournal.com/content/define-if-shell-input-coming-terminal-or-pipe
:-)
You can easily implement a similar behaviour as the "cat" command, that is read from a list of provided files or if they're not provided, then read from the stdin.
Although you may not use this idea, I think this Linux Journal article will be interesting for you http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe
:-)
如果您不想以交互方式运行脚本,请使其将输入文件作为参数,而不是使用
stdin
。有些程序使用标志或特殊文件名来指示它们应该从标准输入而不是文件中获取输入;在这种情况下,您可以在必要时处理命令行操作。如果您希望脚本采用标准输入,为什么不让它具有交互性(或者至少表现得像其他 POSIX 工具一样)?
If you never want to run the script interactively, make it take the input file as a parameter, rather than using
stdin
. Some programs use a flag or a special filename to indicate that they should take input from standard input rather than from a file; that case lets you handle command line jockeying if necessary.If you want your script to take the standard input, why don't you want to let it be interactive (or at least behave like other POSIX tools)?