python - 将标准输出重定向到文件显示错误内容

标签 python linux bash shell

我有一个命名管道“timer_fifo”,python 脚本的标准输出被重定向到 timer_fifo,同时另一个 shell 脚本进程从中读取,处理它,然后将它重定向到另一个名为“activity_file”的文件。

Python 脚本:

import time
while True:
    print(time.strftime('%Y_%m_%d', time.gmtime()))
    time.sleep(1)

执行上面的python脚本:

python above_file_name > timer_fifo

shell 脚本:

while true
do
    read action <timer_fifo;
    echo $action | stdbuf -o0 -e0 -i0 sed -n "s/^\([^[:space:]].*\)/\1 Cinnamon/p" >> activity_file
done

注意:上面的 sed 命令附加 'Cinnamon' 并重定向到事件文件,因此如果输入是 '2017_02_01' 则它变为 '2017_02_01 Cinnamon',如果它以空格开头,它也会忽略输入流。

执行上面的shell脚本:

./file_name

一段时间文件的尾部:

2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon

但过了一会儿文件的尾部:

2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
2017_02_01 Cinnamon
017_02_01 Cinnamon
207_20 Cinnamon
270_1 Cinnamon
210_101_2001_20 Cinnamon
2017_02_0 Cinnamon
270_11207_02_01 Cinnamon
107_20 Cinnamon
0020 Cinnamon

如您所见,为什么输出是乱七八糟的? 另外我可能不止一次执行了上述脚本,那么多个进程同时写入同一个文件会导致排序输出吗?如果是,请解释为什么?

最佳答案

如果您只运行程序的一个副本,那么所有内容都会按顺序到达 fifo,缓冲不会影响顺序。

如果您正在运行程序的多个副本,并且每个副本都在做自己的标准输出缓冲,那么您可能会得到部分行。

我认为这就是您所看到的。

我认为在这种情况下(不完美的)解决方案是在 print()sleep() 之间的 python 脚本中添加一行,如下所示:

sys.stdout.flush()

这将很可能在每次调用 print()/flush() 时,在单个不间断的系统调用中将整行写入 fifo .它仍然不确定——你无法保证原子性。但在实践中,像这样的短字符串将作为单个系统调用。

(您也可以尝试更改 sys.stdout 的缓冲,或使用 python 的运行时标志,但我认为如上所述调用 flush() 是最好的方法。)

来自 sys.stdout docs :当交互时,标准流是行缓冲的。否则,它们会像普通文本文件一样进行 block 缓冲

关于python - 将标准输出重定向到文件显示错误内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41996187/

相关文章:

linux - 在 bash 中使用正则表达式打印文件名

python - 根据相应的 numpy 数组值分割 Dataframe

python - 当在Python字典中找到键时更新值

php - 如何重定向通过 screen -d -m 调用的 PHP 进程的 STDOUT?

linux - 使用 shell 脚本读取 n 个文件的正确方法是什么?

bash - 如何迭代 Bash 脚本中的位置参数?

python - 使用 Jupyter Notebook 从 ipywidget 函数定义全局变量

python - 字符串反转保持空格和大小写

php - LAMP 服务器是否可以在需要时更改其 IP?

bash - subl在终端中工作,但在git中不是默认编辑器