在Linux中使用syscall Read读取STDIN:未使用的输入被发送到bash
以下程序(64位YASM)从标准输入读取4个字节并退出:在Linux中使用syscall Read读取STDIN:未使用的输入被发送到bash,c,linux,bash,assembly,system-calls,C,Linux,Bash,Assembly,System Calls,以下程序(64位YASM)从标准输入读取4个字节并退出: section .data buf db " " ; Just allocate 16 bytes for string section .text global _start _start: mov rax, 0 ; READ syscall mov rdi, 0 ; STDIN
section .data
buf db " " ; Just allocate 16 bytes for string
section .text
global _start
_start:
mov rax, 0 ; READ syscall
mov rdi, 0 ; STDIN
mov rsi, buf ; Address of the string
mov rdx, 4 ; How many bytes to read
syscall
; Exit:
mov rax, 60
mov rdi, 0
syscall
一旦汇编
yasm -f elf64 -l hello.lst -o input.o input.asm
ld -o input input.o
如果它是按
./input
例如,123456\n
作为用户输入,它将消耗1234
,但结束位,56\n
被发送到bash。因此,bash将尝试运行命令56
。。。谢天谢地,没有成功。但是想象一下,如果输入是1234rm-f*
。但是,如果我使用重定向或管道提供输入,例如
echo "123456" | ./input
56
不会发送到bash
那么,如何防止未使用的输入被发送到bash?我是否需要一直使用它,直到遇到某种形式的EOF?这是意料之中的行为吗
在C程序中也会发生同样的情况:
#包括
int main()
{
char-buf[16];
读取(0,buf,4);
返回0;
}
(我只是想知道C运行时是否以某种方式清除了STDIN,但不,它没有)是的,这是正常的行为。您不消费的任何东西都可用于下一个流程。你知道当你做一些慢的事情时,你可以提前键入,当慢的事情完成时,shell将运行你键入的内容吗?这里也一样 没有一刀切的解决方案。这实际上是关于用户的期望。他们希望您的程序消耗多少输入?这就是你应该读的内容
- 您的程序是否像
那样执行单行提示?然后,您应该通过下一个read
字符读取整行输入。不过度阅读的最简单方法是一次读取一个字符。如果进行批量读取,可能会错误地消耗下一行的部分内容\n
- 您的程序是否像
或cat
或sed
这样的过滤器?然后你应该阅读,直到你达到EOFgrep
- 您的程序是否完全不像
或echo
那样从stdin读取数据?然后您应该不使用stdin,不使用任何内容,将输入留给下一个程序gcc
仅消耗4个字节是不寻常的,但对于一个提示输入4位PIN的交互式程序来说可能是合理的行为,并且不需要用户按Enter键。是的,这是正常行为。您不消费的任何东西都可用于下一个流程。你知道当你做一些慢的事情时,你可以提前键入,当慢的事情完成时,shell将运行你键入的内容吗?这里也一样 没有一刀切的解决方案。这实际上是关于用户的期望。他们希望您的程序消耗多少输入?这就是你应该读的内容
- 您的程序是否像
那样执行单行提示?然后,您应该通过下一个read
字符读取整行输入。不过度阅读的最简单方法是一次读取一个字符。如果进行批量读取,可能会错误地消耗下一行的部分内容\n
- 您的程序是否像
或cat
或sed
这样的过滤器?然后你应该阅读,直到你达到EOFgrep
- 您的程序是否完全不像
或echo
那样从stdin读取数据?然后您应该不使用stdin,不使用任何内容,将输入留给下一个程序gcc
read()
syscall,我怀疑您的惊讶可能还与看到使用stdio函数读取标准输入的程序的不同行为有关。这与以下事实有关:当标准输入连接到终端时,默认情况下,stdio函数以行缓冲模式读取它。也就是说,它们将数据从底层源传输到内部缓冲区,从而一次一行地将其从流中删除(有一些警告)
您可以使用读取来模拟这一点。最简单的方法是一次读取一个字节,直到看到换行符或文件结尾,但C库函数通过在标准输入实际上连接到终端时适当配置终端驱动程序来更有效地执行此操作。您也可以直接这样做,但它有点复杂。“发送到”bash(或任何其他程序)是一种次优的思考方式,可能这会导致您的惊讶/困惑。“提供给”将是一个更准确的描述,无论你在说什么