为何使用Bash Here String无法写入STDOUT?
问题分析:Bash Here String 指定文件描述符的误解
首先引用你查阅的Bash手册内容:
Here Strings A variant of here documents, the format is: [n]<<<word The word undergoes tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion and word splitting are not performed. The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).
你对手册中「文件描述符n」的理解出现了偏差:这里的[n]是指定命令要读取的输入文件描述符,而非用来写入的输出文件描述符。Here String本质是输入重定向工具,它的作用是把word的内容提供给命令的某个输入源,不是向某个输出通道写入内容。
为什么你的尝试没有预期效果?
1<<<test无反应
文件描述符1是标准输出(STDOUT),默认处于只写模式。1<<<test试图将test作为输入提供给STDOUT,但没有任何命令去读取这个文件描述符的内容,同时STDOUT本身也不应该被用作输入源,所以这条命令没有实际作用,自然没有输出也不报错。exec 1<<<test报错exec命令用来修改当前shell的文件描述符配置。exec 1<<<test会把当前shell的STDOUT(文件描述符1)重定向为读取Here String的内容,这会将原本只写的STDOUT改成只读模式。之后任何试图向STDOUT写入的命令(比如echo)都会因为文件描述符属性不匹配,抛出Bad file descriptor错误。
正确的用法
Here String是用来给命令提供输入的,比如:
cat <<<test:cat读取默认输入文件描述符0(STDIN)的内容,Here String将test传入STDIN,所以会输出test- 如果要指定非默认的输入文件描述符,比如给命令的文件描述符3提供输入:
# 用read读取文件描述符3的内容 read -u 3 content <<<"hello" echo "$content" # 输出hello
如果只是想向STDOUT写入内容,直接用echo test、printf "%s\n" test这类输出命令即可——Here String从设计上就不是用来做输出重定向的工具。
内容的提问来源于stack exchange,提问作者ton
相关产品推荐
相关产品推荐

