【问题标题】:Testing whether stdin is a file vs. a pipe vs. a tty测试标准输入是文件还是管道还是 tty
【发布时间】:2020-12-17 22:13:53
【问题描述】:

我知道 bash 和 zsh,可以使用例如[ -t 1 ] 确定 STDIN 是否为交互式 tty 会话。

但是,似乎没有办法测试标准输入是从文件重定向还是从命令输入:

foo < ./file
bar | foo 

有什么方法可以检测这两者之间的区别吗?另外,有什么方法可以获取被重定向的文件的路径(在/proc/self 之外,在 macOS 上不可用)?

【问题讨论】:

  • 如果 ./file 是命名管道,你会期待什么样的答案?

标签: bash shell zsh


【解决方案1】:

你可以检查/dev/stdin是普通文件还是管道:

$ cat tmp.sh
#!/bin/bash

if [ -f /dev/stdin ]; then
    echo "file"
elif [ -p /dev/stdin ]; then
    echo "pipe"
fi
$ bash tmp.sh < foo.txt
file
$ echo foo | bash tmp.sh
pipe

不过,这依赖于 /dev/stdin 在您的文件系统中。

您也可以使用stat 命令,该命令将在没有文件名参数的情况下返回有关标准输入的信息。正如您提到的,您使用的是 macOS,您可以使用 %HT 格式:

$ stat -f %HT
Character Device
$ stat -f %HT < foo.txt
Regular File
$ echo foo | stat -f %HT
Fifo File

【讨论】:

  • “Bash 在重定向中使用时会特别处理多个文件名”,包括 /dev/stdin
  • -f /dev/stdin 不是重定向。
猜你喜欢
  • 2016-04-27
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
  • 2011-01-28
  • 2014-04-01
  • 2013-11-06
  • 1970-01-01
相关资源
最近更新 更多