C 为什么stdout重定向与put一起工作而不与write一起工作?

C 为什么stdout重定向与put一起工作而不与write一起工作?,c,unix,io-redirection,C,Unix,Io Redirection,如果我使用put,我可以按预期重定向stdout: #include <stdio.h> int main() { char *s = "hello world"; puts(s); return 0; } 但是,如果我使用write写入stdout,shell重定向将不起作用: #include <stdio.h> #include <string.h> #include <unistd.h> int mai

如果我使用
put
,我可以按预期重定向stdout:

#include <stdio.h>

int main() {
    char *s = "hello world";
    puts(s);    
    return 0;
}
但是,如果我使用
write
写入stdout,shell重定向将不起作用:

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

int main() {
    char *s = "hello world\n";
    write(0, s, strlen(s));
    return 0;
}

为什么会这样?在这种情况下,如何将写入重定向到stdout?

如果您写入stdin,我想您需要这个

write(1, s, strlen(s));

你写进stdin,我想你想要这个

write(1, s, strlen(s));

您的
write
语句正在写入stdin而不是stdout。我很惊讶它居然能起作用

这就是为什么您应该使用常量而不是文字值,因为它不太容易发生此类错误:

write(STDOUT_FILENO, s, strlen(s));

unistd.h
中定义了
STDOUT\u FILENO
STDIN\u FILENO
STDERR\u FILENO

您的
write
语句正在写入STDIN而不是STDOUT。我很惊讶它居然能起作用

这就是为什么您应该使用常量而不是文字值,因为它不太容易发生此类错误:

write(STDOUT_FILENO, s, strlen(s));

unistd.h
中定义了
STDOUT\u FILENO
STDIN\u FILENO
STDERR\u FILENO

之所以有效,是因为没有进行重定向,他是从终端运行的,所以STDIN、STDOUT和STDERR都要到终端,而终端可能是以读/写方式打开的,所以你可以给他们中的任何一个写信(也可以读他们中的任何一个)。没有什么可以依靠的;代码需要修改才能写入stdout。是的,我只是想stdin通常会被限制为只读。这是一个很自然的假设,但我猜很多UN*XE上的登录过程/终端模拟器启动过程只打开了tty的一个,而不是两个,这两个程序都是防止写入stdin或从stdout/stderr读取所需的。之所以有效,是因为没有重定向,他是从终端运行的,所以stdin,stdout和stderr都将连接到终端——终端可能是读/写打开的,因此您可以对其中任何一个进行写入(并从其中任何一个进行读取)。没有什么可以依靠的;代码需要修改才能写入stdout。是的,我只是想stdin通常会被限制为只读。这是一个很自然的假设,但我猜许多UN*XE上的登录过程/终端模拟器启动过程只打开了tty的一个,而不是两个,这两个程序是防止写入stdin或从stdout/stderr读取所需的。如果您在Linux下,并且使用了
strace./.a.out
put()
version,您会发现
put()
使用文件描述符1而不是0调用
write()
。如果您在Linux下,并且使用了
strace./.a.out
put()
版本,您会发现
put()
使用文件描述符1而不是0调用
write()