Linux中"echo -n"命令未被刷新

9

我有以下代码:

while ...
  echo -n "some text"
done | while read; do
  echo "$REPLY" >> file
done

但是当使用“-n”标志时,echo仅起作用。看起来在使用-n时,输出不会被下一个while循环刷新/读取。
如何确保“一些文本”将被读取,即使没有跟随EOL?

1
我无法添加评论,所以我把它放在这里。 你可以去那里 - user4140593
4
读取操作等待“EOL”或输入的结尾,即换行符。 - NishanthSpShetty
@optivian 那么问题不是你所问的,问题不在于输出没有被刷新。NishanthSpShetty的评论可能是正确的。你能否编辑你的问题,避免说不刷新是问题? - user743382
不,相反,在“一些文本”后面加上EOL可以在下一个while循环中读取它。现在它对下一个循环不是“可见的”:(,我可以接受在最后加上额外的EOL。 - optivian
你为什么需要首先使用“-n”? - chepner
显示剩余2条评论
4个回答

4

你无法区分

echo -n "some text"

并且

echo -n "some t"
echo -n "ext"

所以您需要一种分隔规则。通常使用EOL进行分隔。通过-d,read支持自定义分隔符,或者可以通过-n或-N基于字符数进行拆分。例如,您可以使read在每个符号上触发:

echo -n qwe | while read -N 1 ch; do echo $ch; done

read 的行为让我感到惊讶。在 (something which produces output) | read 的情况下,EOF 不应该表示最后一行的结束吗?所以 read 会说:“我应该读取行,但这不是行,请忘记它”? - Peter - Reinstate Monica
3
read 读取一行文本,POSIX 明确将一行文本定义为以换行符结束。如果 read 到达不以换行符结尾的文件末尾,它仍会将变量填充为它所能够读取的内容,但是由于无法读取完整的一行,它会返回一个非零退出状态表示失败。 - chepner
你还应该使用 echo 输出空格和换行符。 - Walter A

1
你可以从定义自己的分隔符开始:
while :; do
  echo -n "some text"
  sleep 2
done | while read -d' ' reply; do
  echo "-$reply-"
done

这将打印:

-some-
-textsome-
-textsome-

对于电子邮件,也许使用 . 作为分隔符是有意义的,但您需要决定一些分词方案。


谢谢,但那不是我想要的 - 有些文本可能是动态的,我不知道分隔符...也许可以在while循环完成后放置EOL,并将其附加到流中,在下一个循环中读取输入? - optivian
是的,根据你的问题需要做一些事情。 - perreal

1
解决方法是(按照原始示例):
while ...
  echo -n "some text"
done | (cat && echo) | while read; do 
  echo "$REPLY" >> file
done

这将在测试流中添加行尾,并允许read读取它。副作用是在流的末尾会有一个额外的行尾。

0

你可以让read每次读取一个字符,但是应该添加一些内容来读取特殊字符(换行符、空格):IFS=
我想展示我真正捕捉了这些字符,所以我会将回复大写。

i=0
while (( i++<5 )) ; do
  echo -n "some text $i. "
  sleep 1;
done | while IFS= read -rn1 reply; do
  printf "%s" "${reply^^}"
done

这个解决方案有一个特点:您将看不到任何换行符。 当您也想看到它们时,您需要进行修复

i=1
while (( i++<5 )) ; do
  echo -n "some text $i.
second line."
  sleep 1;
done | while IFS= read -rn1 reply; do
  if (( ${#reply} == 0 )); then
     echo
  else
     printf "%s" "${reply^^}"
  fi
done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接