Причина в том, что вы используете scanf
, который читает из потока стандартного ввода. Он использует буферы, поэтому он попытается прочитать данные из одного буфера и только затем проверит, сколько этих данных ему действительно нужно. Поскольку ваша команда ls
доступна немедленно, она также будет прочитана в буфер, ожидая другого вызова scanf (или любой другой буферизованной функции stdio, работающей на стандартном вводе ). Поэтому, когда sh
затем пытается прочитать со стандартного ввода, ничего не остается, поскольку он не видит буфер, который является внутренним для вашей программы на C.
Есть как минимум два способа решить эту проблему.
Убедитесь, что команда «ls» не выводится на стандартный ввод до того, как scanf завершит чтение. Это немного сложно, так как вам нужно будет подождать, пока ваша программа выведет доказательства прохождения этой точки (не тривиально ), или затем использовать некоторую фиксированную задержку и надеяться, что система никогда не остановится в этой точке и сделает задержка слишком короткая (т.е. это хрупкое решение ).Последний будет выглядеть примерно так :(echo 3 ; sleep 1 ; echo ls) | myprogram
, т. е. три команды выполняются по порядку, и все они обеспечивают ввод для myprogram
.
Вы используете функции для чтения из стандартного ввода -без буферов -только минимальное количество необходимых символов. Например, функция read
не использует буферы. Вы можете написать вспомогательную функцию, например
#include
#include
#include
#include
int unbuffered_scanf(const char *fmt,...) {
char buffer[100]; // maximum line length
int i;
int ret;
for(i=0; i 0)
system("/bin/sh");
else
printf("Goodbye!\n");
}
Для получения дополнительной информации о небуферизованных функциях прочтите информационные страницы, например, здесь:https://www.gnu.org/software/libc/manual/html_node/I_002fO-Primitives.html#I_002fO-Primitives
РЕДАКТИРОВАТЬ:По-видимому, есть способ отключить буферизацию, выполняемую scanf
и другими, используя, например,. функция setbuf
-она, вероятно, работает внутренне точно так же, как мой пример выше:
#include
#include
int main()
{
int iRetval = 0;
unsigned int uiNum;
setbuf(stdin, NULL);
printf("Enter number: ");
fflush(stdout);
iRetval = scanf("%u", &uiNum);
printf("\nThe number is %u, Retval: %i\n", uiNum, iRetval);
fflush(stdout);
if( iRetval > 0)
system("/bin/sh");
else
printf("Goodbye!\n");
}
printf "This is my first line\n > bigfile.new
. tail
из bigfile
для предоставления остальных, используя перенаправление добавления:>>
. Одно замечание:tail +2
заключается в том, что "GNUism" -будет работать в большинстве дистрибутивов Linux, но не совместим с POSIX и, вероятно, не будет работать в других Unices.
Предполагая bash
и Linux, это, вероятно, быстрее, чем код в вашем вопросе:
(echo "New headers";tail +2 bigfile.txt) > newbigfile.txt && mv newbigfile.txt bigfile.txt