Предположим, у нас есть следующая программа с именем myprog
:
#include <stdio.h>
#include <stdlib.h>
void main(){
char buffer[32];
gets(buffer);
system("/bin/sh");
}
- Занимает место для буфера
- Он ожидает данных со стандартного ввода и копирует их в буфер до тех пор, пока не будет найдена новая строка.
- Он выполняет оболочку как дочерний процесс, затем он будет ждать команд от стандартного ввода
Итак, у нас есть 2 инструкции, которые будут искать данные из stdin.
Предположим, мы хотим передать эти данные, перенаправляя стандартный вывод других программ на стандартный ввод myprog
, возьмем, например, echo
и cat
.
$ cat > cmds
ls
$ { echo "My string" ; cat cmds ; } | ./myprog
file1 file2 cmds myprog
Пока все хорошо: echo
автоматически добавляет символ новой строки в конец «Моя строка», это заставляет gets
прекращать чтение и /bin/sh
читать из вывода cat
.
Но попробуем другие решения:
echo "My string" ls | ./myprog
printf "My string\nls\n" | ./myprog
{echo "My string" ; echo ls ; } | ./myprog
Ни одно из этих решений, похоже, не работает. Также не работает использование одного файла и одного вызова cat
:
$ cat > file
My string
ls
$ cat file | ./myprog
Почему так происходит? Что именно происходит в каждом из этих случаев?
gets
ужасен. - person Etan Reisner   schedule 28.10.2015cat
- это внешняя программа, и есть небольшая задержка при запускеcat
между выводом My string и содержимым файла. Во всех других ваших примерахbash
внутренние элементы используются для вывода обеих строк. Это означает, чтоgets
может читать не только первую строку и буферизовать ее для следующего вызоваgets
, что означает, что/bin/sh
не получает ожидаемые данные. Вы можете подтвердить, заменив/bin/sh
наcat
, чтобы увидеть, что на самом деле находится в стандартном вводе при вызовеsystem
. - person chepner   schedule 28.10.2015gcc myprog.c -o myprog
@EtanReisner. Я знаю, что это ужасно, это просто пример. @chepner Вы правы, первая явно неверна, моя ошибка. Вы правы и в отношении времени: после использованияsystem("cat")
и просмотра содержимого буфера я вижу, что что-то вроде{ echo "My string" ; sleep 1 ; echo ls ; }
работает правильно. Спасибо. С другой стороны,{echo "My string" ; echo ls ; }
заставляетgets
сохранять в буфере только"My string"
.ls
все еще идет на входgets
без копирования? - person TTK   schedule 28.10.2015