C 프로그램을 사용하여 터미널에서 명령을 실행하는 방법은 무엇입니까?


11

터미널에서 명령을 실행할 수있는 C 언어로 프로그램을 만들고 싶습니다.

브라우저에서 열린 웹 사이트의 IP를 제공하는 쉘 스크립트로 프로그램을 만들었습니다. 이 쉘 스크립트는 터미널에 다음 명령을 입력하여 실행됩니다.

sudo tcpdump -n dst port 80 -i eth

교수님은 터미널을 열고이 명령을 입력하는 C 언어로 된 프로그램을 만들라고했는데 쉘 스크립트가 작동합니다.

그러한 프로그램을 만드는 방법을 알려주십시오.

답변:


8

당신이 사용할 수있는 시스템 () 에서 사용 가능한 기능을 stdlib.h 실행 명령에.

기술

system ()은 / bin / sh -c string을 호출하여 string에 지정된 명령을 실행하고 명령이 완료된 후 반환합니다. 명령을 실행하는 동안 SIGCHLD가 차단되고 SIGINT 및 SIGQUIT는 무시됩니다.

http://linux.about.com/library/cmd/blcmdl3_system.htm에 대한 자세한 내용을 볼 수 있습니다.


이것은 확실히 한 가지 방법이지만 ac 프로그램에서 명령을 실행하지 않으려는 대신 대부분의 Linux 프로그램에는 프로그램의 코드를 직접 할 수있는 lib가 있습니다. 예를 들어 ssh는 libssh 를 사용할 수 있습니다 . 일반적으로 코드에서 시스템 명령을 실행해야하는 이유는 매우 제한적입니다. 당신이 그것을 많이한다면 거의 확실하게 뭔가 잘못하고 있습니다.
coteyr

나는 이런 식으로 C 프로그램을 만들었습니다
Tehseen Malik

4

안녕하세요, 예제 코드를 작성하여 설명해 드리고 이것이 실제로 도움이 되길 바랍니다. 함수의 프로토 타입은 다음과 같습니다.

int 시스템 (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). 그것을 실행하십시오 (예 : 우분투에서) ./program_name comman_name -anything-anything

예 : ./a.out 로케일 -a

이 예제는 컴파일러에서 지원하는 모든 로케일 인 gcc를 인쇄합니다.

더 많은 정보:

p는 argv와 같은 char을 가리키는 포인터입니다. p = & argv [2], -anything 문자열을 가리 킵니다.-모두 cmd 문자열을 가리 킵니다. * p가 NULL을 가리킬 때 루프를 종료합니다 :-> 이 기호를 사용하여 포인트를 말합니다 (오른쪽 화살표 선택 연산자와 혼동하지 마십시오).

argv [0]-> program_name

argv [1]-> command_name (이 예제에서 명령 이름은 로케일이지만 대신 확인하려는 명령을 입력하십시오)

argv [2]-> -anything (이 예에서는 -a, 모든 로케일 임)

argv [3]-> NULL (이 예에서는 루프를 종료합니다)

알았어요.


명백한 버퍼 오버플로 익스플로잇을 가지고 있기 때문에 이것을 setuid 실행 파일로 사용하지 마십시오.
Martin

0

나는 이것이 임의의 명령 실행이 아닌 sudo를 대체하기 위해 setuid-root 바이너리를 사용하는 것이라고 가정 할 것이므로 솔루션의 다른 부분을 포함시킬 것입니다.

보안상의 이유로, 우리는 하이재킹 될 수 있기 때문에 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을 반환합니다. }
    만약 (setuid (0) 1) p [6] = argv [1];

    / * 모든 것이 잘되면 execv는 반환하지 않습니다.
     * (이 프로그램은 tcpdump로 대체되었으므로) * /
    execv (p0, p);
    / * 여기에 도달하면 execv가 실패했을 것입니다 * /

    perror (p0);
    EX_OSFILE을 반환;
}

이것을로 저장 foo.c하고으로 설치 /usr/local/sbin/foo하려면 다음을 실행하십시오.

foo를 만드십시오 && install -o root -m 4511 foo / usr / local / sbin / foo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.