加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – 如何在不使用stdbuf和类似工具的情况下解除传统运行二进

发布时间:2020-12-15 21:25:39 所属栏目:安全 来源:网络整理
导读:我想监视我将要开始的程序的实时输出.我试图通过将程序的输出重定向到管道,然后从监视脚本中读取管道来实现此目的. ./program apipe 然后从监控脚本 cat apipe 但是由于中的缓冲区没有输出.无论如何我可以禁用此缓冲区?我在一个准系统嵌入式系统(petalinux)
我想监视我将要开始的程序的实时输出.我试图通过将程序的输出重定向到管道,然后从监视脚本中读取管道来实现此目的.

./program >> apipe

然后从监控脚本

cat apipe

但是由于>>中的缓冲区没有输出.无论如何我可以禁用此缓冲区?我在一个准系统嵌入式系统(petalinux)上运行,因此我无法访问unbuffer,脚本或stdbuf来帮助我.

我已经尝试了另一个平台上的脚本,其中unbuffer可用,它可以正常工作.

我可以用任何方式配置此缓冲区,或使用其他二进制文件重定向?

编辑:我无法访问我尝试运行的命令的源代码.它是传统的二进制文件.

解决方法

如果您无法访问stdbuf,您也可以模拟它并使用gdb手动取消缓冲stdout(假设您显然可以访问gdb).

我们来看看stdbuf实际上是如何运作的. stdbuf GNU coreutils命令基本上只通过设置LD_PRELOAD环境变量在用户程序中注入libstdbuf. (不相关,但为了记录,选项通过_STDBUF_E / _STDBUF_I / _STDBUF_O env vars传递.)

然后,当运行libstdbuf时,它在适当的文件描述符(stdin / stdout / stderr)上调用setvbuf libc函数(进而执行底层系统调用),具有适当的模式(完全缓冲,行缓冲或无缓冲).

setvbuf的声明在stdio.h中,可以与man 3 setvbuf一起使用:

#include <stdio.h>

int setvbuf(FILE *stream,char *buf,int mode,size_t size);

模式的值为:_IONBF,_IOLBF,_IOFBF,如stdio.h中所定义.我们这里只对无缓冲模式感兴趣:_IONBF.它的值为2(您可以检查/usr/include/stdio.h).

Unbuffer脚本

因此,要为一些进程解除stdout,我们只需要调用:

setvbuf(stdout,NULL,_IONBF,0)

我们可以使用gdb轻松完成.让我们创建一个我们可以调用的脚本unbuffer-stdout.sh:

#!/bin/bash
# usage: unbuffer-stdout.sh PID

gdb --pid "$1" -ex "call setvbuf(stdout,2,0)" --batch

然后,我们可以这样称呼:

$./unbuffer-stdout.sh "$(pgrep -f my-program-name)"

(你可能需要sudo以root身份运行它.)

测试

我们可以使用带有缓冲标准输出的这个简单的Python程序(如果没有使用-u调用,并且使用未设置的PYTHONUNBUFFERED),writer.py:

#!/usr/bin/python
import sys,time

while True:
    sys.stdout.write("output")
    time.sleep(0.5)

运行它:

$./writer.py >/tmp/output &
$tailf /tmp/output

并且在我们运行之前观察没有输出:

$sudo ./unbuffer-stdout.sh "$(pgrep -f writer.py)"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读