У меня нет под рукой CentOS, но я могу говорить, исходя из большого опыта работы с Debian.
Вообще говоря, конфигурации моста требуют, чтобы сам интерфейс (в вашем случаеenp0s25
)не был настроен с IP-адресом. Физический интерфейс остается ненастроенным, но ВКЛЮЧЕН и РАБОТАЕТ, а конфигурация IP для хоста вместо этого применяется к интерфейсу логического моста.
Я предлагаю изменить файл ifcfg-enp0s25
на ONBOOT=no
и повторить попытку.
Если это не сработает, удалите ifcfg-enp0s25
файл (, т.е. переместите его в безопасное место ), потому что у вас есть необходимые настройки в подчиненном файле.
Вы должны запрограммировать возможность обработки команды pipe из оболочки.
См., например, такие ссылки, как Программа на C для демонстрации вилки и конвейера:
Пример:
int fd[2];
pipe(fd);
fd[0]; //-> for using read end
fd[1]; //-> for using write end
В вашем примере вам нужно добавить код для обработки полученных данных (и всего, что необходимо передать обратно в вызывающую оболочку ).
Причина в том, что вы используете scanf
, который читает из потока стандартного ввода. Он использует буферы, поэтому он попытается прочитать данные из одного буфера и только затем проверит, сколько этих данных ему действительно нужно. Поскольку ваша команда ls
доступна немедленно, она также будет прочитана в буфер, ожидая другого вызова scanf (или любой другой буферизованной функции stdio, работающей на стандартном вводе ). Поэтому, когда sh
затем пытается прочитать со стандартного ввода, ничего не остается, поскольку он не видит буфер, который является внутренним для вашей программы на C.
Есть как минимум два способа решить эту проблему.
Убедитесь, что команда «ls» не выводится на стандартный ввод до того, как scanf завершит чтение. Это немного сложно, так как вам нужно будет подождать, пока ваша программа выведет доказательства прохождения этой точки (не тривиально ), или затем использовать некоторую фиксированную задержку и надеяться, что система никогда не остановится в этой точке и сделает задержка слишком короткая (т.е. это хрупкое решение ).Последний будет выглядеть примерно так :(echo 3 ; sleep 1 ; echo ls) | myprogram
, т. е. три команды выполняются по порядку, и все они обеспечивают ввод для myprogram
.
Вы используете функции для чтения из стандартного ввода -без буферов -только минимальное количество необходимых символов. Например, функция read
не использует буферы. Вы можете написать вспомогательную функцию, например
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
int unbuffered_scanf(const char *fmt,...) {
char buffer[100]; // maximum line length
int i;
int ret;
for(i=0; i<sizeof(buffer)-1; ++i) {
if (!read(0, &buffer[i], 1)) break;
if (buffer[i] == '\n') break;
}
buffer[i] = '\0';
va_list ap;
va_start(ap, fmt);
ret = vsscanf(buffer, fmt, ap);
va_end(ap);
return ret;
}
int main()
{
int iRetval = 0;
unsigned int uiNum;
printf("Enter number: ");
fflush(stdout);
iRetval = unbuffered_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");
}
Для получения дополнительной информации о небуферизованных функциях прочтите информационные страницы, например, здесь:https://www.gnu.org/software/libc/manual/html_node/I_002fO-Primitives.html#I_002fO-Primitives
РЕДАКТИРОВАТЬ:По-видимому, есть способ отключить буферизацию, выполняемую scanf
и другими, используя, например,. функция setbuf
-она, вероятно, работает внутренне точно так же, как мой пример выше:
#include <stdio.h>
#include <stdlib.h>
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");
}