mob*_*eng 1 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
mov rsi, buf ; Address of the string
mov rdx, 4 ; How many bytes to read
syscall
; Exit:
mov rax, 60
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
一旦编译
yasm -f elf64 -l hello.lst -o input.o input.asm
ld -o input input.o
Run Code Online (Sandbox Code Playgroud)
如果它像这样运行
./input
Run Code Online (Sandbox Code Playgroud)
比如说,123456\n
作为用户输入,它将消耗1234
,但结束位56\n
被发送到 bash。因此,bash 将尝试运行该命令56
……幸好没有成功。但是想象一下,如果输入是1234rm -f *
. 但是,如果我使用重定向或管道提供输入,例如,
echo "123456" | ./input
Run Code Online (Sandbox Code Playgroud)
56
不会发送到 bash。
那么,如何防止将未使用的输入发送到 bash?在遇到某种形式的 EOF 之前,我是否需要继续使用它?这甚至是预期的行为吗?
同样的事情发生在 C 程序中:
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
Run Code Online (Sandbox Code Playgroud)
(我只是想知道 C 运行时是否以某种方式清除了 STDIN,但不,它没有)
是的,这是正常行为。您不消耗的任何东西都可用于下一个过程。您知道如何在执行缓慢的操作时可以提前输入,而当执行缓慢的操作完成时,shell 将运行您输入的内容吗?这里也是一样。
没有一刀切的解决方案。这真的是关于用户的期望。他们期望您的程序消耗多少输入?这就是你应该阅读的内容。
您的程序是否像单行提示一样read
?然后,您应该通过下一个\n
字符读取整行输入。不过度阅读的最简单方法是一次阅读 1 个字符。如果您进行批量读取,您可能会错误地消耗下一行的一部分。
您的程序是否像过滤器一样cat
或sed
或grep
?然后你应该阅读直到你到达 EOF。
您的程序是否根本不从标准输入读取echo
或gcc
?然后你应该不理会 stdin 并且不消耗任何东西,将输入留给下一个程序。
正好消耗 4 个字节是不寻常的,但对于提示输入 4 位 PIN 且不需要用户按 的交互式程序来说可能是合理的行为Enter。
归档时间: |
|
查看次数: |
222 次 |
最近记录: |