当您的程序作为管道的一部分启动时,
前一个进程通过管道传输到程序的标准输入。所以你可以
做:
int main(void)
{
char line[1024];
fgets(line, sizeof line, stdin);
printf("First line is: %s\n", line);
return 0;
}
在 POSIX 系统上,您可以使用isatty 来检查文件描述符是否属于
指终端。例如:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
if(isatty(STDIN_FILENO))
puts("stdin connected to terminal");
else
puts("piped data to stdin");
return 0;
}
程序的标准行为是从stdin 读取并写入
stdout。通过坚持这一点,您可以使用 shell 链接您的程序
管道|.
例如cat 期望在没有文件传递的情况下从标准输入中读取
作为论据。 cat 的一个简单实现是:
int main(int argc, char **argv)
{
FILE *in = stdin;
if(argc == 2)
{
in = fopen(argv[1], "r");
if(in == NULL)
{
perror("fopen");
return 1;
}
}
int c;
while((c = fgetc(in)) != EOF)
fputc(c, stdout);
if(in != stdin)
fclose(in);
return 0;
}
作为一名程序员,在阅读 stdin 时,我并不关心
用户在终端中输入输入,或者输入是否通过管道输入。相同
写信给stdout 是真的。作为用户,我知道像cat 这样的程序
当没有文件通过时从stdin 读取并写入stdout。因为
这种行为我能做到的
$ echo "hi" | cat | sort
所以你也应该模仿这种行为。
当然,有时最好知道是否涉及管道。例如
git diff 写信给stdout 有颜色和没有颜色
git diff | more。在这种情况下,可以检查stdout 的连接位置
to,但是写stdout的行为是一样的。
#include <stdio.h>
#include <unistd.h>
void print_colored_message(const char *msg)
{
printf("\x1b[31m%s\x1b[0m\n", msg);
}
void print_message(const char *msg)
{
if(isatty(STDOUT_FILENO))
print_colored_message(msg);
else
puts(msg);
}
int main(void)
{
print_message("Hello");
print_message("World");
return 0;
}
复制并粘贴此程序并以./test 和./test | less 执行一次。
你会看到在第一个版本中你得到一个彩色输出,而在
第二个版本你没有。保持不变的是输出是在
stdout.
如果您不希望您的程序以这种方式被链接,那么您必须告诉
你的用户不应该在这样的链条中使用你的程序。