Как использовать программу на C для запуска команды на терминале?

11

Я хочу создать программу на языке Си, которая позволила бы мне запустить команду в терминале.

Я сделал программу в сценарии оболочки, которая даст мне IP-адрес любого веб-сайта, который открывается в моем браузере. Этот сценарий оболочки выполняется путем ввода этой команды в терминал:

sudo tcpdump -n dst port 80 -i eth

Мой профессор сказал мне создать программу на языке C, которая открывала бы терминал и вводила эту команду, и тогда мой сценарий оболочки работал бы.

Подскажите пожалуйста, как создать такую ​​программу.

Техсин Малик
источник

Ответы:

8

Вы можете использовать функцию system (), доступную в stdlib.h для запуска команд.

ОПИСАНИЕ

system () выполняет команду, указанную в строке, вызывая / bin / sh -c строку, и возвращает после завершения команды. Во время выполнения команды SIGCHLD будет заблокирован, а SIGINT и SIGQUIT будут игнорироваться.

Вы можете прочитать больше об этом здесь http://linux.about.com/library/cmd/blcmdl3_system.htm

Мевин Бабу
источник
Это, безусловно, один из способов, но вы, вероятно, не хотите запускать команды из программ переменного тока, вместо этого большинство программ Linux имеют библиотеку, которая может напрямую кодировать программы. Например, ssh может использовать libssh . Обычно ОЧЕНЬ ограниченная причина для запуска системных команд из кода. Если вы делаете это много, вы почти наверняка делаете что-то не так.
coteyr 9.12.12
Я сделал программу на C, как это
Tehseen Malik
4

Здравствуйте, я напишу для вас пример кода, объясню его вам и очень надеюсь, что это поможет вам. прототип функции выглядит примерно так:

int system (const char * cmd);

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CMN_LEN 100

int main(int argc, char *argv[])
{
    char cmd[MAX_CMN_LEN] = "", **p;

    if (argc < 2) /*no command specified*/
    {
        fprintf(stderr, "Usage: ./program_name terminal_command ...");
        exit(EXIT_FAILURE);
    }
    else
    {
        strcat(cmd, argv[1]);
        for (p = &argv[2]; *p; p++)
        {
            strcat(cmd, " ");
            strcat(cmd, *p);
        }
        system(cmd);
    }

    return 0;
}

1). откройте терминал и скомпилируйте программу

2). запустите его (например, в Ubuntu) ./program_name comman_name -anything - что угодно

пример: ./a.out locale -a

этот пример печатает все локали, поддерживаемые моим компилятором gcc.

больше информации:

p - это указатель на указатель на char (как и argv) p = & argv [2], указывает на что-либо строку, я перебираю все что угодно в моей строке cmd, я выхожу из цикла, когда * p указывает на NULL, посмотрите на это: -> я буду использовать этот символ для обозначения точек (не путайте его с оператором выбора стрелки вправо).

argv [0] -> имя_программы

argv [1] -> имя_команды (в этом примере имя команды будет локаль, но введите команду, которую вы хотите проверить вместо)

argv [2] -> -anything (в этом примере -a, все локали)

argv [3] -> NULL (в этом примере это выходит из цикла)

хорошо, вот и все, я думаю.

Nemka
источник
Убедитесь, что вы не используете это как исполняемый файл setuid, потому что он имеет явную уязвимость переполнения буфера.
Мартин
0

Я собираюсь предположить, что речь идет об использовании двоичного файла setuid-root для замены sudo, а не просто произвольного выполнения команд, поэтому я собираюсь включить другие части решения.

В целях безопасности мы избегаем system (), потому что он может быть взломан.

После компиляции установите полученный бинарный файл как setuid-root.

#include <unistd.h>
#include <stdio.h>
#include <sysexits.h>

int main (int argc, char ** argv) {
    if (argc> 2) {fputs ("слишком много аргументов \ n", stderr); возврат EX_USAGE; }
    if (argc> 1 && argv [1] [0] == '-') {fputs ("опции не разрешены \ n", stderr); возврат EX_USAGE; }
    if (geteuid ()! = 0) {fputs ("неправильно установлен как setuid-root \ n", stderr); возврат EX_UNAVAILABLE; }
    if (setuid (0) 1) p [6] = argv [1];

    / * Если все пойдет хорошо, execv не вернется
     * (потому что эта программа будет заменена на tcpdump) * /
    execv (p0, p);
    / * если мы доберемся сюда, значит, execv потерпел неудачу * /

    PError (р0);
    возврат EX_OSFILE;
}

если вы сохранили это как foo.cи хотите установить как /usr/local/sbin/foo, запустите:

сделать foo && установить -o root -m 4511 foo / usr / local / sbin / foo
Мартин
источник