如何使用 read() 系统调用将用户输入脚本化到程序中?
How to script user input into program using read() syscall?
我在 Linux 环境中使用几个二进制文件,我正在尝试编写用户输入的脚本。例如,第一个程序 prog1.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
fgets(buffer, 31, stdin);
printf("Your input: %s\n", buffer);
i++;
}
}
我可以 运行 prog1 并直接从控制台输入输入,或者我可以编写输入脚本并将其通过管道传输到程序中。
直接从控制台输入:
# ./prog1
Enter input: Stuff1
Your input: Stuff1
Enter input: Stuff2
Your input: Stuff2
Enter input: Stuff3
Your input: Stuff3
#
脚本输入:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1
Enter input: Your input: Stuff1
Enter input: Your input: Stuff2
Enter input: Your input: Stuff3
#
虽然输出的格式有点乱,程序仍然显示预期的输出。
我的问题是第二个二进制文件 prog2.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
read(0, buffer, 31);
printf("Your input: %s\n", buffer);
i++;
}
}
当我可以直接从控制台输入时:
# ./prog2
Stuff1
Enter input: Your input: Stuff1
Stuff2
Enter input: Your input: Stuff2
Stuff3
Enter input: Your input: Stuff3
#
不仅输入提示在我输入之后才出现,而且我什至无法编写输入脚本:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2
Enter input: Your input: Stuff1
Stuff2
Stuff3
Enter input: Your input:
Enter input: Your input:
#
我研究了 fgets()
和 read()
之间的差异,发现:
fgets()
是 C 函数,而 read()
是系统调用。
fgets()
读取输入直到遇到换行符或 EOF,而换行符对 read()
系统调用没有相同的影响。
read()
采用了某种 fgets()
没有的缓冲机制。
我认为第 2 点和第 3 点与手头的问题最相关,但它们没有提示我如何解决我的问题。
我需要给这些程序的用户输入涉及不可打印的十六进制字节,这就是为什么直接从控制台输入此类输入是不够的。我也无法修改二进制文件的源代码,因此没有解决方法只能使用 fgets()
来收集输入。
我的问题是是否有任何方法可以将输入提供给 prog2,以便我获得与 prog1 相同的行为。
谢谢。
read(2)
不缓冲,但 fgets/printf/etc
从 <stdio.h>
做以获得更好的性能。
如果你想阅读台词,坚持使用fgets
。但是如果你想读取不可打印的数据块(即二进制),使用 fread
。在任何情况下,检查 return 值。
读取 'binary' 文件(可以包含 NUL 字节等)时使用 'read()' 或 'fread()'
读取文本文件时,使用'fgets()'
我找到了解决此问题的方法。我仍然无法按照我想要的方式与二进制文件交互 - 从控制台编写我的输入脚本 - 但我找到了一种以编程方式进行的方法。
我正在使用 Python 库套件作为 subprocess
模块的包装器,但您可以简单地编写自己的:
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
这会将二进制文件作为进程打开,然后您可以使用 Python 脚本中的发送和接收函数与其进行交互。
我希望这对遇到类似问题的其他人有所帮助。
我在 Linux 环境中使用几个二进制文件,我正在尝试编写用户输入的脚本。例如,第一个程序 prog1.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
fgets(buffer, 31, stdin);
printf("Your input: %s\n", buffer);
i++;
}
}
我可以 运行 prog1 并直接从控制台输入输入,或者我可以编写输入脚本并将其通过管道传输到程序中。
直接从控制台输入:
# ./prog1
Enter input: Stuff1
Your input: Stuff1
Enter input: Stuff2
Your input: Stuff2
Enter input: Stuff3
Your input: Stuff3
#
脚本输入:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1
Enter input: Your input: Stuff1
Enter input: Your input: Stuff2
Enter input: Your input: Stuff3
#
虽然输出的格式有点乱,程序仍然显示预期的输出。
我的问题是第二个二进制文件 prog2.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
read(0, buffer, 31);
printf("Your input: %s\n", buffer);
i++;
}
}
当我可以直接从控制台输入时:
# ./prog2
Stuff1
Enter input: Your input: Stuff1
Stuff2
Enter input: Your input: Stuff2
Stuff3
Enter input: Your input: Stuff3
#
不仅输入提示在我输入之后才出现,而且我什至无法编写输入脚本:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2
Enter input: Your input: Stuff1
Stuff2
Stuff3
Enter input: Your input:
Enter input: Your input:
#
我研究了 fgets()
和 read()
之间的差异,发现:
fgets()
是 C 函数,而read()
是系统调用。fgets()
读取输入直到遇到换行符或 EOF,而换行符对read()
系统调用没有相同的影响。read()
采用了某种fgets()
没有的缓冲机制。
我认为第 2 点和第 3 点与手头的问题最相关,但它们没有提示我如何解决我的问题。
我需要给这些程序的用户输入涉及不可打印的十六进制字节,这就是为什么直接从控制台输入此类输入是不够的。我也无法修改二进制文件的源代码,因此没有解决方法只能使用 fgets()
来收集输入。
我的问题是是否有任何方法可以将输入提供给 prog2,以便我获得与 prog1 相同的行为。
谢谢。
read(2)
不缓冲,但 fgets/printf/etc
从 <stdio.h>
做以获得更好的性能。
如果你想阅读台词,坚持使用fgets
。但是如果你想读取不可打印的数据块(即二进制),使用 fread
。在任何情况下,检查 return 值。
读取 'binary' 文件(可以包含 NUL 字节等)时使用 'read()' 或 'fread()'
读取文本文件时,使用'fgets()'
我找到了解决此问题的方法。我仍然无法按照我想要的方式与二进制文件交互 - 从控制台编写我的输入脚本 - 但我找到了一种以编程方式进行的方法。
我正在使用 Python 库套件作为 subprocess
模块的包装器,但您可以简单地编写自己的:
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
这会将二进制文件作为进程打开,然后您可以使用 Python 脚本中的发送和接收函数与其进行交互。
我希望这对遇到类似问题的其他人有所帮助。