You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用write系统调用实现echo命令时输出字符长度异常原因排查

为什么用write系统调用实现echo会输出异常?

问题重现

正常工作的printf实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    while (--argc)
        printf(((argc == 1) ? "%s\n" : "%s "), *++argv);
}

运行结果:

$ ./a.out Bring a towel
Bring a towel

输出异常的write实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    while (--argc) {
        write(STDOUT_FILENO, *++argv, strlen(*argv));
        write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
    }
}

运行结果:

$ ./a.out Bring a towel
Bringa atow t

问题原因

核心问题在于write系统调用不保证一次性写入所有请求的字节数。

当调用write时,操作系统可能因为输出缓冲区已满、设备繁忙等原因,只写入部分字节,并返回实际写入的字节数。你直接忽略了write的返回值,没有处理部分写入的情况,导致部分字符未被输出,后续的write操作拼接了不完整的内容,最终出现混乱的输出。

相比之下,printf属于标准IO库函数,内部已经封装了循环写入的逻辑,会自动处理部分写入的情况,确保所有数据都被输出。

另外,你尝试的fflush(stdout)对write无效——write绕过了标准IO的缓冲区,直接操作内核缓冲区,fflush仅对标准IO的缓冲区生效。

解决办法

实现一个封装函数,确保所有请求的字节都被写入:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// 确保完整写入所有字节的封装函数
ssize_t full_write(int fd, const void *buf, size_t count) {
    const char *ptr = buf;
    size_t remaining = count;
    while (remaining > 0) {
        ssize_t written = write(fd, ptr, remaining);
        if (written == -1) {
            perror("write failed");
            return -1;
        }
        remaining -= written;
        ptr += written;
    }
    return count;
}

int main(int argc, char *argv[]) {
    while (--argc) {
        full_write(STDOUT_FILENO, *++argv, strlen(*argv));
        full_write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
    }
    return 0;
}

这个函数会循环调用write,直到所有字节都被写入或遇到错误,从而保证输出内容完整且正确。

内容的提问来源于stack exchange,提问作者Mate de Vita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:24:52