下面是一个脚本,用于检查 stdin 的来源,
来自 How-to Geek:“Linux 上的 stdin、stdout 和 stderr 是什么?”
https://www.howtogeek.com/435903/what-are-stdin-stdout-and-stderr-on-linux/
#!/bin/bash
if [ -t 0 ]; then
echo stdin coming from keyboard
else
echo stdin coming from a pipe or a file
fi
那么如果任何命令带有参数或命令替换执行,它与 没有任何关系吗stdin
?在这种情况下是stdin
空的吗?
虽然我能理解来自管道或文件的含义,但来自键盘的stdin
含义是什么?是像命令或文档中的按键输入那样的吗?stdin
read
感谢社区每天的支持。
答案1
command line arguments
为了解释和之间的区别stdin
。我将把我的答案分成几个部分来解释底层概念。然后回答你的问题。
在我开始解释之前,请记住以下几点:
- 在 Linux 中,一切事物都被视为文件。
- 我假设您已经阅读了问题中提供的整个帖子。
- 我将借助 C 程序来解释其中的区别,因此我假设您了解基本语法。不过,我还是会尽可能多地解释。
标准输入和命令行参数
标准输入是 Linux 的一个文件,程序可以访问它来获取用户的输入。任何程序都不能直接与键盘交互,而是与 交互stdin
。因此,如果程序需要从用户那里获取输入,它将访问stdin
。
当您将重定向 ( > or <
) 或管道 ( |
) 与其他命令一起使用时,它会操纵输入和输出流,即stdin
和stdout
。当您指定这些特殊字符时,它们会指示stdin
并stdout
说明如何运行。在 Linux 中,stdin
是/proc/self/fd/0
, 和stdout
是/proc/self/fd/1
命令行参数基本上是一种从使用中获取输入以及调用命令以使命令执行某些特定任务的方法。每个程序不需要有命令行参数,因为是否使用它们取决于以下程序的开发人员。
命令行参数以数组的形式传递给命令。(数组是由元素集合组成的数据结构,每个元素由至少一个数组索引或键标识。)。因此,程序员可以使用该数组中的值向其程序添加更多功能。
C 程序示例
#include<stdio.h>
int main(int argc, char *argv[]) {
if(argc==2)
printf("Welcome Master %s\n", argv[1]);
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
在上面的程序中,程序不接受来自用户的任何标准输入,但是它接受命令行参数,并且根据是否提供参数而以不同的方式工作。
argc
是一个变量,用于存储传递的参数数量,argv
是一个数组,用于存储调用程序时传递的参数。argv[0]
是数组中的第一个元素,包含程序本身的名称。之后数组将包含传递的参数。
当我通过输入“./batman”执行以下程序时,我得到以下输出:
用法:./batman
但当我通过输入“./batman Bruce”执行同一程序时,我得到:
欢迎布鲁斯大师
现在这并不意味着该程序无法接受输入。下面是修改后的程序,它接受命令行参数和标准输入。
#include<stdio.h>
int main(int argc, char *argv[]) {
int pass = 0;
if(argc==2){
printf("Welcome Master %s\n", argv[1]);
printf("Kindly provide password : ");
scanf("%d", &pass);
if(pass==1234)
printf("Batcave Access granted\n");
else
printf("Batcave Access declined\n");
}
else {
fprintf(stderr, "Usage : %s <name>\n", argv[0]);
return 1;
}
return 0;
}
上面的代码接受一个命令行参数,然后等待用户通过标准输入输入密码。
如果我们不指定任何参数,它将像之前的 C 代码一样抛出错误。
以下是程序执行时的输出:
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Bruce Welcome Master Bruce Kindly provide password : 1234 Batcave Access granted mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman3 Joker Welcome Master Joker Kindly provide password : 123 Batcave Access declined mars@HP-Notebook:~/Desktop/Practice/cpp$
传递命令行参数后,该程序等待用户输入密码,因此通过stdin
那么结论是什么?
我希望你理解了我上面解释的概念。现在是时候回答这些问题了。- 是的,命令行参数与此无关
stdin
,stdin
在这种情况下只是指向您的输入设备但未被使用。 stdin
本身是一个文件,默认情况下指向您的输入设备并从那里获取输入。但是,当您在命令中提供管道或重定向时,它会告诉stdin
从您指定的文件而不是连接到您计算机的输入设备获取输入。
如果你不理解 C 程序也没关系。这次我们使用内置命令来代替自定义程序。
命令代替程序的示例:
cat file_name
cat < file_name
输出将是相同的,因为相应的开发人员cat
要么从文件中读取数据stdin
,要么从文件中读取数据,该文件的名称作为第一个命令行参数(这是 shell 传递给 cat 的数组中的第一个元素)。
随后 cat 将 file_name 的全部内容写入stdin
终端,因为我们没有指示 shell 操作stdout
。请记住,在第二行中,您的 shellstdin
以这种方式进行操作,它不再指向您的标准输入设备,而是指向当前工作目录中名为 file_name 的文件。此示例取自另一篇文章,您可以点击此处阅读更多内容
我希望这不仅为您提供了问题的解决方案,而且还帮助您理解潜在的概念。