标准流只是变量吗?

标准流只是变量吗?

当我运行命令时,例如test -l --hello check
shell将命令保存到变量,$0="test"shell执行 相应的二进制文件$1="-l"二进制 文件读取变量 二进制文件执行变量所说的操作$2="--hello"$3="check"


标准流只是这些变量吗?


对@philip-couling 的问题(我在这里问是因为评论有限):

我认为您想询问重定向运算符和管道:<、>、|。

是的,标准流这就是重定向和管道的工作原理,对吧?

将文本行分解为参数

它保存参数/标志以及命令本身。例如,ls 是命令部分,-la 是参数部分。这很重要,例如,对于busybox来说,它只是一个二进制文件,并且通常使用符号链接调用(如果您运行例如/bin/ls(在路径so ls中),它是到/bin/busybox的符号链接,busybox二进制文件需要一种方法来知道命令及其标志)。

作为数组传递给命令

作为数组?它不使用 $0..$∞ 变量?

当您打开文件进行读取或写入时,操作系统会为您提供一个“文件描述符”,它只是一个数字。子进程从其父进程继承文件描述符。在父级中打开的任何文件也将打开并可供子级使用(除非文件是在明确指示不打开的情况下打开的)。

每个文件描述符只是一个数字。前三个用于 stdin(0) stdout(1) stderr(2)。请参阅 posix 中的 STDERR_FILENO。据我所知,这些在技术上并不是保留的,但事实上这三个描述符通常存在,防止其他人使用相同的号码。

软件语言可能有特殊的语法来写入标准输出(如 echo 或 print),但实际上二进制文件所做的只是写入文件描述符编号 0。

哦,现在我记得文件描述符和 stdin、stdout、stderr 是 0、1、2。对这些的解释真的很好!但问题是,命令的所有输出都转到 1 和 2,对吧?那么,1和2什么时候会被清除呢?

答案1

我认为您想询问重定向运算符和管道:<, >, |

对于命令行参数,shell 会将文本行分解为参数,以数组形式传递给命令。 shell 调用fork创建一个新进程,然后用于exec启动新命令并传递参数。

对于重定向来说,情况有点复杂。文件名不直接传递。相反,标准流是从父进程继承的,shell 必须在fork和之间修改它们exec

当您打开文件进行读取或写入时,操作系统会为您提供一个“文件描述符”,它只是一个数字。子进程从其父进程继承文件描述符。在父级中打开的任何文件也将打开并可供子级使用(除非文件是在明确指示不打开的情况下打开的)。

每个文件描述符只是一个数字。前三个用于 stdin(0) stdout(1) stderr(2)。看STDERR_FILENO在 posix 中。据我所知,这些在技术上并不是保留的,但事实上这三个描述符通常存在,防止其他人使用相同的号码。

软件语言可能有特殊的语法来写入标准输出(如echoprint),但实际上二进制文件所做的只是写入文件描述符编号 0。

重定向运算符的工作方式是,shell 打开文件或创建一个管道来获取文件描述符,然后调用dup2将描述符复制到三个 (0,1,2) 之一,然后再调用exec.

因此子进程永远不会被告知它在 stdin、stdout 或 stderr 上打开了什么。它只有文件描述符,如果它询问操作系统,它可能能够获得更多信息。

相关内容