Cプログラムを使用して端末でコマンドを実行する方法


11

端末でコマンドを実行できるようにするC言語のプログラムを作成したいと考えています。

私は、ブラウザで開いているWebサイトのIPを取得するプログラムをシェルスクリプトで作成しました。このシェルスクリプトは、ターミナルで次のコマンドを入力して実行されます。

sudo tcpdump -n dst port 80 -i eth

教授から、ターミナルを開いてこのコマンドを入力するC言語のプログラムを作成するように言われました。そうすれば、シェルスクリプトが機能します。

そのようなプログラムの作り方を教えてください。

回答:


8

stdlib.hにあるsystem()関数を使用してコマンドを実行できます。

説明

system()は、/ bin / sh -c stringを呼び出すことによってstringで指定されたコマンドを実行し、コマンドが完了した後に戻ります。コマンドの実行中、SIGCHLDはブロックされ、SIGINTおよびSIGQUITは無視されます。

詳細については、http://linux.about.com/library/cmd/blcmdl3_system.htmを参照してください。


これは確かに1つの方法ですが、おそらくacプログラムからコマンドを実行したくないでしょう。代わりに、ほとんどのLinuxプログラムには、プログラムのコードだけを直接実行できるlibがあります。たとえば、sshはlibsshを使用できます。通常、コードからシステムコマンドを実行する理由は非常に限られています。あなたがそれをたくさん行っているなら、ほとんど間違いなく何か間違ったことをしています。
coteyr

私はこのように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]、-anything string i cat all -anythings to my cmd string iループを終了します* pがNULLを指すとこれを見てください:->この記号を使用してポイントを指します(右矢印選択演算子と混同しないでください)。

argv [0]-> program_name

argv [1]-> command_name(この例ではコマンド名はロケールですが、代わりに確認するコマンドを入力してください)

argv [2]-> -anything(この例では、すべてのロケールである-a)

argv [3]-> NULL(この例では、ループを終了します)

それでいいと思います。


これは明らかにバッファオーバーフローを悪用するため、これを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( "too many args \ n"、stderr); EX_USAGEを返します。}
    if(argc> 1 && argv [1] [0] == '-'){fputs( "no options allowed \ n"、stderr); EX_USAGEを返します。}
    if(geteuid()!= 0){fputs( "not set installed as setuid-root \ n"、stderr); EX_UNAVAILABLEを返します。}
    if(setuid(0)1)p [6] = argv [1];

    / *すべてがうまくいくと、execvは戻りません
     *(このプログラムはtcpdumpに置き換えられるため)* /
    execv(p0、p);
    / *ここに到達したら、execvが失敗したに違いありません* /

    perror(p0);
    EX_OSFILEを返します。
}

これをとして保存し、としてfoo.cインストールする場合は/usr/local/sbin/foo、次のコマンドを実行します。

make foo && install -o root -m 4511 foo / usr / local / sbin / foo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.