什么" ... |发球台"将stdin(标准输入)转移到两个地方:stdout(标准输出)和名为" file"的路径/文件。实际上它是这样做的,据我所知:
#!/bin/bash
var=(cat) # same as var=(cat /dev/stdin)
echo -e "$var"
for file in "$@"
do
echo -e "$var" > "${file}"
done
exit 0
所以我使用上面的代码来创建tee1以查看我是否可以模拟tee所做的事情。但我的真正意图是编写一个附加到现有文件的修改版本,而不是从头开始重做它们。我称之为tee2:
#!/bin/bash
var=(cat) # same as var=(cat /dev/stdin)
echo -e "$var"
for file in "$@"
do
echo -e "$var" >> "${file}"
done
exit 0
这对我有意义,但不是为了打击。现在另一种方法是做这样的事情:
echo -e "$var"
for file in "$@"
do
echo -e "$var"| tee tmpfile
cat tmpfile >> "${file}"
done
rm tmpfile
exit 0
这对我来说也很有意义:
#!/bin/bash
cp -rfp /dev/stdin tmpfile
cat tmpfile
for file in "$@"
do
cat tmpfile >> "${file}"
done
exit 0
或者这个:
#!/bin/bash
cat /dev/stdin
for file in "$@"
do
cat /dev/stdin >> "${file}"
done
exit 0
一些在线搜索建议使用printf代替echo -e,以便跨平台更加一致。其他建议使用cat代替读取,虽然因为stdin是一个设备,它应该可以用来代替catm,如:
> tmpfile
IFS=\n
while read line
do
echo $line >> tmpfile
echo $line
done < /dev/stdin
unset IFS
然后是for循环。但我无法让它发挥作用。我怎么能用bash来做呢?
答案 0 :(得分:4)
但我的真正意图是编写一个附加到现有文件的修改版本,而不是从头开始重做它们。
指定tee
实用程序以支持-a
选项,这意味着“将输出附加到文件”。 [spec]
(我不知道tee
的任何实现在这方面偏离了规范。)
编辑添加:如果您的问题确实是“我尝试的所有不同内容出了什么问题”,那么,对于单个Stack Overflow问题,这可能过于宽泛。但这里有一个简短的清单:
var=(cat)
表示“将数组变量var
设置为包含单个元素,即字符串cat
。”
cat
。var=$(cat)
,这意味着“运行命令cat
,捕获其标准输出。丢弃任何空字节,并丢弃任何尾随的换行序列。将结果保存在常规变量中{ {1}}“。
var
也没有用,因为tee
不会丢弃空字节和尾随换行符。此外,tee
在输入可用时转发输入,而tee
必须等待输入完成。 (如果标准输入来自终端,这是一个问题 - 在这种情况下,用户希望看到他们的输入回显 - 或者来自可能尝试与用户通信的程序 - 在这种情况下,你会得到一个死锁。)var=$(cat)
重点处理echo -e "$var"
之类的转义序列。 (这就是\t
的意思。)这不是你想要的。此外,如果您设法正确设置-e
,它会附加一个额外的换行符,这不是您想要的换行符。 (如果没有设法正确设置$var
,那么这可能有助于弥补这一点,但它不能真正解决问题。)
$var
的内容,您应该写var
。printf %s "$var"
方法。到目前为止,它并没有改进任何东西,它引入了现在如果您要复制到 n 文件的错误,那么您还将编写 n 副本到标准输出。 (但是你在以后的版本中修复了这个bug。)| tee tmpfile
的版本(每个目的地一次)将无效,因为标准输入没有“倒带”。一旦消耗掉了东西,它就消失了。 (当您考虑标准输入经常在程序之间传递时,这是有道理的 - 例如,您的cat /dev/stdin
- s从您的Bash脚本继承它,并且您的Bash脚本可能从终端继承它如果发生某种自动倒带,它将如何决定返回的距离?)(注意:如果标准输入来自常规文件,那么明确地可以向后搜索它,从而“消耗”已消耗的输入。但这不会自动发生,无论如何,当标准输入来自终端,管道等时,这是不可能的。)