为什么 `cat <(cat)` 会产生 EIO?

2023-11-21

我有一个程序可以同时读取两个输入文件。我想让这个程序从标准输入读取。我想我会用这样的东西:

$program1 <(cat) <($program2)

但我刚刚发现

cat <(cat)

produces

....
mmap2(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb758e000
read(0, 0xb758f000, 131072)             = -1 EIO (Input/output error)
....
cat: -: Input/output error

同样,

$ cat <(read -n 1)
bash: read: read error: 0: Input/output error

所以... Linux 无法read在系统调用级别。那很有意思。是bash没有将标准输入连接到子shell? :(

有针对这个的解决方法吗?我特别需要使用进程替换(... <(...)格式)因为$program1 (tail顺便说一句)需要文件,我需要做一些预处理(用od)在标准输入上,然后我可以将其传递给tail- 我不能只指定/dev/stdin et al.

EDIT:

我真正想做的是从文件中读取(另一个进程将写入该文件),而我also从标准输入读取,这样我就可以接受命令等。我希望我能做到

tail -f <(od -An -vtd1 -w1) <(cat fifo)

从标准输入读取and同时将 FIFO 放入单个标准输出流中,我可以通过 awk (或类似的)运行。我知道我可以用任何脚本语言轻松解决这个问题,但我喜欢学习如何制作bash做一切事情:P

编辑2:我问过一个新问题这更充分地解释了我上面描述的背景。


1. 解释原因cat <(cat)产生EIO

( 我正在使用 Debian Linux 8.7、Bash 4.4.12 )

我们来替换一下<(cat)随着长期运行<(sleep)看看发生了什么。

From pty #1:

$ echo $$
906
$ tty
/dev/pts/14
$ cat <(sleep 12345)

去另一个pty #2:

$ ps t pts/14 j
  PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
   903    906    906    906 pts/14    29999 Ss       0   0:00 bash
   906  29998    906    906 pts/14    29999 S        0   0:00 bash
 29998  30000    906    906 pts/14    29999 S        0   0:00 sleep 12345
   906  29999  29999    906 pts/14    29999 S+       0   0:00 cat /dev/fd/63
$ ps p 903 j
  PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
     1    903    903    903 ?            -1 Ss       0   0:07 SCREEN -T linux -U
$

让我解释一下(根据APUE书,第二版):

  1. The TPGID being 29999表明cat (PID 29999) 是现在控制终端的前台进程组 (pts/14). And sleep位于后台进程组(PGID906).
  2. 进程组为906现在是一个孤立进程组因为“每个成员的家长要么本身是该组的成员,要么不是该组会话的成员”。 (PID906的 PPID 是903 and 903在不同的会话中。)
  3. 当孤立后台进程组中的进程从其控制终端读取时,read()会失败EIO.

2. 解释原因cat <(cat)有时works(并不真地!)

丹尼尔·沃伊纳在评论中提到cat <(cat) works在 OS X 上使用 Bash3.2.57。我刚刚设法在 Linux 上用 Bash 重现它4.4.12.

From pty #1:

bash-4.4# echo $$
10732
bash-4.4# tty
/dev/pts/0
bash-4.4# cat <(cat)
cat: -: Input/output error
bash-4.4#
bash-4.4#
bash-4.4# bash --norc --noprofile  # start a new bash
bash-4.4# tac <(cat)
                      <-- It's waiting here so looks like it's working.

(首先cat <(cat)失败了EIO我的答案的第一部分已对此进行了解释。)

去另一个pty #2:

bash-4.4# ps t pts/0 j
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
10527 10732 10732 10732 pts/0    10805 Ss       0   0:00 bash
10732 10803 10803 10732 pts/0    10805 S        0   0:00 bash --norc --noprofile
10803 10804 10803 10732 pts/0    10805 S        0   0:00 bash --norc --noprofile
10804 10806 10803 10732 pts/0    10805 T        0   0:00 cat
10803 10805 10805 10732 pts/0    10805 S+       0   0:00 tac /dev/fd/63
bash-4.4# ps p 10527 j
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
10526 10527 10527 10527 ?           -1 Ss       0   0:00 SCREEN -T dtterm -U
bash-4.4#

让我们看看发生了什么:

  1. The TPGID being 10805表明tac (PID 10805) 是现在控制终端的前台进程组 (pts/0). And cat (PID 10806) 位于后台进程组 (PGID10803).

  2. 但这一次 pgrp10803不是孤立的,因为它的成员 PID10803 (bash) 的父级 (PID10732, bash) 位于另一个 pgrp (PGID10732)并且它在同一个会话中(SID10732).

  3. 根据APUE书, SIGTTIN“当(非孤立)后台进程组中的进程尝试从其控制终端读取时,由终端驱动程序生成”。所以当cat读取标准输入,SIGTTIN将被发送给它,默认情况下该信号将stop的过程。这就是为什么cat's STAT列显示为T(停止)在ps输出。由于它已停止,我们从键盘输入的数据根本不会发送给它。所以它只是好像它有效,但实际上并非如此。

结论:

所以不同的行为(EIO vs. SIGTTIN)取决于当前 Bash 是否是会话领导者。 (在我的回答的第一部分中,PID的bash906是会话领导者,但是 bash 的 PID10803第二部分不是会议主持人。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 `cat <(cat)` 会产生 EIO? 的相关文章

  • 我的 unix 脚本出了什么问题

    bin bash while echo n Player s name read name name ZZZ do searchresult grep name playername if searchresult 0 then echo
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • 此 bash 命令在 Makefile 中未正确运行

    在 Makefile 里面我有这样的 release version poetry version cut f2 d echo release version 如果我运行 我的终端中的语句将毫无问题地运行 gt version poetry
  • 将“npm run start”的输出写入文件

    我想捕获的输出npm run start在一个文件中 我遇到了大量错误 我想更好地控制如何筛选输出 当我尝试时 npm run start gt log txt 我得到一个非常简短的文件 8 行 其结尾为 34m 39m 90m wdm 3
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 如何显示 zsh 函数定义(如 bash“type myfunc”)?

    如何在 zsh 中显示函数的定义 type foo没有给出定义 在bash中 bash function foo echo hello bash foo hello bash type foo foo is a function foo e
  • Bash 脚本大小限制?

    我有一个 bash 脚本 在 RHEL 或 OS X 上运行时出现以下错误 第 62484 行 意外标记 换行符 附近出现语法错误 第 62484 行 o gz 这是一个自动生成的脚本 用于解决我公司使用的 Grid Engine 计算集群
  • 如何使用我在 github 中发布的 bash 脚本执行 chsh?

    我有一个要点 我总是用它来在新服务器上安装我需要的软件包 http gist github com 4372049 http gist github com 4372049 我需要做的就是通过 ssh 在新服务器中输入以下内容 bash c
  • 使用带有curl 的内部字段分隔符

    当我做 ls IFS l 我得到了我期望的输出 当我做 curl IFShttp www google com 我不 我是否误解了内部字段分隔符 如何在不使用任何空格字符的情况下运行curl 命令 您需要将变量放在大括号内 否则 shell
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • Haskell 输入返回元组

    我想知道 IO 函数是否可以返回元组 因为我想从这个函数中获取这些元组作为另一个函数的输入 investinput IO gt Char Int investinput do putStrLn Enter Username username
  • bash 行长度限制从何而来?

    在运行 Bash 4 4 19 标准安装 的 Solaris 11 上 输入行似乎有 256 个字符的限制 我想了解这个限制从何而来 我浏览了手册页 但没有找到任何解决此问题的内容 仅当未使用 readline 库时才会发生这种情况 在下面
  • 如何在数组中存储包含双引号的命令参数?

    我有一个 Bash 脚本 它生成 存储和修改数组中的值 这些值稍后用作命令的参数 对于 MCVE 我想到了任意命令bash c echo 0 0 echo 1 1 这解释了我的问题 我将用两个参数调用我的命令 option1 without
  • 如何判断 Bash 中是否存在文件?

    这会检查文件是否存在 bin bash FILE 1 if f FILE then echo File FILE exists else echo File FILE does not exist fi 我如何只检查文件是否存在not ex
  • Git difftool 未启动外部 DiffMerge 程序

    我一直遵循 戴夫的博客条目 http www davesquared net 2009 05 setting up git difftool on windows html 链接在此answer https stackoverflow co
  • 动态参数值取决于另一个动态参数值

    启动前提 非常严格的环境 Windows 7 SP1 Powershell 3 0 使用外部库的可能性有限或不可能 我正在尝试重写之前创建的 bash 工具 这次使用 PowerShell 在 bash 中 我实现了自动完成功能 以使该工具
  • 如何将 emscripten 浏览器输入法从 window.prompt 更改为更合理的输入法?

    我有一个 C 函数 一旦调用它就会消耗来自 stdin 的输入 使用 emscripten 将此函数导出到 javascript 会导致调用 window prompt 与浏览器提示交互确实是一项乏味的任务 首先 您一次只能粘贴一行 其次
  • 从标准输入读取字符串长度[重复]

    这个问题在这里已经有答案了 我想从标准输入获取一个字符串 但我不想要固定大小的静态数组 我知道 scanf 需要保存标准输入的东西 但我不能做这样的事情 char string 10 scanf s string 因为我需要先知道字符串有多
  • 从 php 执行 bash 脚本并立即输出回网页

    我有一组 bash 和 Perl 脚本 开发在 Linux Box 上部署所需的目录结构 可选 从svn导出代码 从这个源构建一个包 这在终端上运行良好 现在 我的客户请求此流程的 Web 界面 例如 某些页面上的 创建新包 按钮将一一调用
  • 如何在shell中输出返回码?

    我正在尝试通过调用自定义 shell 脚本sh bin sh c myscript sh gt log txt 2 gt 1 echo 该命令的输出是创建的后台进程的 PID 我想指导 bin sh保存返回码myscript sh到某个文件

随机推荐

  • SBT 0.10 和 IDEA 初学者指南

    我是 SBT 新手 不确定如何开始项目 有人可以向我指出创建 Hello World 类型项目的初学者指南 或者给我一些线索吗 我首选的 IDE 是 IDEA 我跑了sbt idea根据说明IDEA 插件页面 目前我有点困惑 因为 没有创建
  • 从 Rails 返回文件

    初学者铁路问题 如何从 Rails 中的控制器返回文件 我熟悉返回 渲染 JSON 对象 但是我从未返回 渲染带有任意扩展名的文件 从阅读周围所以听起来像render nothing gt true有帮助 我只是在寻找一些指导或相关文档 您
  • 如何使用 dplyr 编程语法来创建和计算变量名称

    我想使用 dplyr 编程语法动态输入变量名 但是 正如许多人所描述的那样 这可能非常令人困惑 我尝试过各种 quo enquo 的组合 等等都无济于事 这是我的代码的最简单形式 library tidyverse df lt tibble
  • 按指定顺序按 id 查找 ActiveRecord 对象的简洁方法

    我想获取给定 id 数组的 ActiveRecord 对象数组 我假设 Object find 5 2 3 将返回一个依次包含对象 5 对象 2 对象 3 的数组 但我得到的数组按对象 2 对象 3 对象 5 的顺序排列 ActiveRec
  • 使用 WinAPI 进行简单的 AES 加密

    我需要在我的 Qt C 应用程序中进行简单的单块 AES 加密 解密 这是一个 让诚实的人诚实 的实现 所以只是一个基本的encrypt key data 是必要的 我不担心初始化向量等 我的输入和密钥将始终恰好是 16 个字节 I d r
  • 在网络上获取 Python 脚本输出的最简单方法是什么?

    我有一个连续运行的 python 脚本 它每 30 秒输出 2 行信息 我希望能够在网络上查看此输出 特别是 我希望网站能够自动更新 每 30 秒在页面 网站顶部添加新输出 而无需刷新页面 我知道我可以用 javascript 做到这一点
  • GWT:在服务器代码中访问 i18n 消息

    我有一个扩展的接口com google gwt i18n client Messages类 我用它在 GWT 应用程序中检索 i18n 消息 它看起来像这样 public interface MyMessages extends com g
  • jQuery 触发 DatePicker 更改事件

    我有以下代码 custom datepicker selector datepicker weekStart 1 on changeDate function en var correct format correct format en
  • 未标记 AcceptVerbs、HttpGet 或 HttpPost 的控制器操作的默认行为是什么?

    如果我创建一个控制器操作并且不使用它来装饰它AcceptVerbs HttpPost or HttpGet 默认行为是什么 该操作是否允许任何访问方法或默认为GET 它可以通过任何动词访问
  • java中equals方法的实现

    这是我对 Coor 类的 equals 类的实现 它只包含 2 个整数 x 和 y 这是实现该方法的正确方法吗 public boolean equals Object obj if obj null obj getClass this g
  • Python3 Tkinter 字体不工作

    我将 python 3 3 与 tkinter 一起使用 并且安装了 python3 tk 包 在大多数文档中 使用旧的 import tkFont 它不再起作用 这应该有效 from tkinter import font appHigh
  • C++ 中的虚拟网络摄像头

    我想编写一个新的虚拟网络摄像头驱动程序 例如它将采用 AVI 或实时流作为屏幕并将其作为网络摄像头源进行流式传输 我真的不会有网络摄像头 我想添加一个可以传输桌面屏幕的虚拟网络摄像头 我应该在内核模式下编写一个网络摄像头来做到这一点 如果是
  • 遍历并修改dict结构的树状列表

    我有一个如下所示的结构 id 4 children None id 2 children id 1 children id 6 children None id 5 children None id 7 children id 3 chil
  • 拳击会导致性能问题吗?

    我正在开发一个项目 其中我们正在生成一种编译为 java 的语言 我们使用的框架 xtext 在其生成的代码中大量使用了装箱 具体来说 如果您有如下声明 int i 1 int j 2 int k i j 然后编译后的代码如下所示 Inte
  • ESLint:创建下一个应用程序时选项无效

    我正在创建一个新的 Next js 应用程序 当我跑步时yarn create next app我开始在 Visual Studio Code 中编写 javascript 代码 每次我输入数字时 ESlint 扩展都会返回一个错误 当然
  • 如何在 Grails 中更新外部配置文件而不重建 war 文件

    如何更新外部配置文件 例如 config ex groovy config ex properties 而不在 Grails 中重建 war 文件 重新启动应用程序服务器将应用外部配置文件中的新更新 如果我理解得很好的话 你想在战争之外外部
  • 反向 Java Graphics2D 缩放和旋转坐标

    我使用Java中的Graphics2D来缩放和旋转我绘制的图片 我现在希望能够在单击图片中的某个点时知道原始坐标是什么 因此 鉴于旋转和缩放的坐标 我想计算原始坐标 有没有一种简单的方法可以做到这一点 如果您保留一份副本AffineTran
  • Python 中 module.__init__() 最多接受 2 个参数错误

    我有 3 个文件 factory imagenet py imdb py 和 imagenet py factory imagenet py 有 import datasets imagenet 它还有一个函数调用为 datasets im
  • maven命令中-D表示什么?

    谁能解释一下 D 在 maven 命令中表示什么 mvn clean install DskipTests 您定义了一个可由Maven 插件 or 在 pom 内部使用 gt mvn help usage mvn options Optio
  • 为什么 `cat <(cat)` 会产生 EIO?

    我有一个程序可以同时读取两个输入文件 我想让这个程序从标准输入读取 我想我会用这样的东西 program1 lt cat lt program2 但我刚刚发现 cat lt cat produces mmap2 NULL 139264 PR