• ベストアンサー

popen() について。

Cのプログラムでpopen()を使って別のプログラムを実行したいのですが、popen("ABC","r")の"ABC"をプログラム実行者側で指定できるようにしたいのですが、可能でしょうか?? (例えば、実行時に引数をlsと指定すると、”ABC”がlsになってlsが実行される、のような) popen("Argv[1]","r")のようにしても上手くいきません。。 どなたかご教授お願いします。

  • felon
  • お礼率52% (12/23)

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

Perlじゃないんだからそういう書き方しても interpolationしてくれませんから。 ということで、 char cmd[64]; //サイズは適当に調整してください snprintf(cmd, sizeof cmd, "%s", argv[1]); とか strlcpy(cmd, argv[1], sizeof cmd); して popen(cmd, "r"); と実行。 それから、ユーザーから入力をもらって それをノーチェックで実行するのは *とっても危険*ですので、ちゃんとチェックしましょう。

felon
質問者

お礼

ちゃんと動作できました。ありがとうございます! 後学のために聞きたいんですが、どうしてチェックしないと「とっても危険」なのでしょうか??

その他の回答 (3)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

> 後学のために聞きたいんですが、どうしてチェックしないと「とっても危険」なのでしょうか?? たとえばの話 rm -rf / とか渡されたらどうします?(笑) これはファイルやディレクトリのパーミッションで 助かるかもしれませんが、いずれにしろ ナニが入ってくるかわからないわけですから、 きちんとチェックしましょうね、ということです。 ってまあどういうチェックをどこまでやるとの言うのは 結構面倒な問題だったりするのですが。 あと、渡されるコマンドの出力をどうしたいのかが わからなかったので#1の回答では popenをそのまま使いましたが、 単にコマンドが実行できれば良いということなら、 #2のzwiさんの書かれたとおりで、systemなり 何なりを使った方が良いです。

felon
質問者

お礼

解答していただいた皆さん、本当にありがとうございました。 とっても参考になりました。 なぜpopenなのかなんですが、、自分の見たサイトではsystemよりpopenの方がよいと書いてあったからです。(私の解釈ミスかもしれませんが) systemで出来ました。確かにこっちの方が良さそうですね。 危険性などについての解答もありがとうございました。 また機会があればよろしくお願いいたします。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

>後学のために聞きたいんですが、どうしてチェックしないと「とっても危険」なのでしょうか?? 自分のコンピュータに自分で入力するのなら直接コマンド入力するのと変わりないでそれほど問題にはなりにくいです。でも使用できるコマンドに制限をつけるとかチェックは入れておいたほうが良いでしょう。 問題なのはその入力が他人からされる可能性のあるもので、悪意のあるコマンドでファイルの内容を読まれたりファイルを書き換えられたり削除されたりする危険性が有ります。 インターネットの初期ではこういう脆弱性のあるCGIが結構ありました。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

popen(Argv[1],"r")で実行できると思います。 しかしなぜpopenなのでしょうか?パイプを使いますか? ただ起動したいだけならsystem(Argv[1])だと思うのですが。 ちなみにWindowsだと"ShellExecute"とかを使います。 http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpshell/html/_win32_shellexecute.asp

関連するQ&A

  • プログラム実行時に引数"<"を指定したい。

    自分でも色々調べたのですが、手に負えなかったので質問させていただきます。何度も質問する形になって申し訳ないです。 今取り組んでいる課題の1つに、プログラム実行時に引数として"<"と"ABC"(ABCはファイル名)を指定するとABCに書かれたスクリプトを実行する。というものがあります。 myprogram < scriptfile(←のような感じです) それで、第1引数が"<"なら第2引数のファイルを実行する。というようにしようと思ったのですが、Argv[1]に"<"が格納されません。 引数に"<"を指定すると別の処理をするらしいことは調べたのでわかったのですが、どうにか"<"を格納できないでしょうか?(つまりは、引数が"<"の時とそうでない時で分岐できるようにしたいのです) あと、スクリプトのファイル名もArgv[2]に格納できないんですが、第2引数に指定された文字列はどこへ行ってしまったんでしょうか? 何度もすいませんがよろしくお願いいたします。

  • popen について

    popen() を使いこなせるようになろうとしているのですが、少し難しくてつまづいています。この関数は基本的に、指定したスクリプトをバックグラウンドで実行させるためのもの、と考えてよろしいでしょうか? マニュアルを読んでわからなかった言葉があります。「パイプ」「片方向ストリーム」 なのですが、検索して、パイプはなんとなく出入力先のポートだということが書いてあったのですが、いまいちピンときません。パイプを経由することで生まれるメリットのようなものはあるのでしょうか? 次に、ファイルポインタなのですが、スクリプトを実行させるのになぜこれが必要になるのでしょうか?おそらくほとんどのスクリプトがファイルの先頭にポインタを置く必要があると思うのですが、例えば'a'などとして、最後に置くとスクリプトが実行されなくなったりしませんでしょうか? 現在の理解度では popen("php -f $script", "r"); exec("php -f $script > /dev/null &"); の違いがわかりません。どちらも$sriptをバックグラウンドで実行してくれますが、マニュアルに記載されているファイルポインタの指定とパイプのオープンがもたらす決定的な違いなどどのようなものになるのでしょうか? また、popen()使用後に、pclose() で閉じないでいるとどのようなことが起こるのでしょうか? たくさんありますが、ひとつでもお分かりになるかたおられましたらどうぞよろしくお願いいたします。

    • 締切済み
    • PHP
  • popen・pcloseについて

    popen・pcloseについて 以下のようにpopenを使ってdirコマンドを打った時と同じようなプログラムを Microsoft Visual C++ 2008上で作ったのですが #include <stdio.h> int main(void) { FILE *fp; char buff[64]; fp=popen("dir","r"); while(fgets(buff,sizeof(buff),fp)!=NULL){ printf("%s",buff); } pclose(fp); return 0; } これをビルドした所、以下のようなエラーが出てしまいました。 c:\users\yamaomoto\documents\visual studio 2008\projects\popen\popen\popen.c(8) : warning C4013: 関数 'popen' は定義されていません。int 型の値を返す外部関数と見なします。 c:\users\yamaomoto\documents\visual studio 2008\projects\popen\popen\popen.c(8) : warning C4047: '=' : 間接参照のレベルが 'FILE *' と 'int' で異なっています。 c:\users\yamaomoto\documents\visual studio 2008\projects\popen\popen\popen.c(14) : warning C4013: 関数 'pclose' は定義されていません。int 型の値を返す外部関数と見なします。 popen.obj : error LNK2019: 未解決の外部シンボル _pclose が関数 _main で参照されました。 popen.obj : error LNK2019: 未解決の外部シンボル _popen が関数 _main で参照されました。 C:\Users\Yamaomoto\Documents\Visual Studio 2008\Projects\popen\Debug\popen.exe : fatal error LNK1120: 外部参照 2 が未解決です。 色々と試してみたのですが解決に至りませんでしたのでよろしければ、 教えて頂けませんでしょうか?

  • UNIX関数?(popen)について

    Cプログラムでpopen関数?を使用しコマンド(rcp)を実行するプログ ラムを造ったのですが、当分が動作していたのですが、何のタイミングか分からないのですが、失敗する時が有ります。一度失敗するとそれ以降はずーと失敗します 。どのような原因が考えられるのでしょうか? ちなみにプログラムの一部をとりあえずのせておきます。(ファイル名及び相手先 のディレクトリ名は現状存在します) 又、system関数とpopen関数の大きな違いは何でしょうか? ご教示お願い致します。 (cプログラムの一部) char buff[256] ; char cmnd[256] ; /* コマンド文字列 */ int fp_rtc ; memset( buff, NULL, sizeof(buff) ) ; memset( cmnd, NULL, sizeof(cmnd) ) ; strcpy( buff, argv[1] ) ; sprintf(cmnd, RCP_FMT , buff, RCP_DIR, buff ) ; printf( "rcp cmnd ( %s )\n", cmnd ) ; fp = popen(cmnd, "r") ; fflush(stdout) ; fp_rtc = pclose(fp) ; if ( fp_rtc != 0 ){ printf( "pclose err [ rtc:%d ] \n", fp_rtc ) ; }

  • Perlでpopen()的なものを使って・・

    今Perlでちょっとしたアプリを作っています。 サーバはunix系でアプリの内容はコマンドの結果値をHTMLで表示させるというものです。 一度Cで作って成功しました。 簡単に書きます。(HTMLの表示部分は簡略します) int main() { char *token; char str[1024]; FILE *fp = popen("ls -la","r"); while(fgets(str,1024,fp)!=NULL){ token = strtok(str,NULL); printf("結果:%s\n",token); } exit(0); } とコマンド(例:ls -la)を実行してファイルハンドルを返してコマンドの結果値を読み取って表示させるというものなのですが、これをPerlに移行したいと考えています。 Perlをさわるのが初めてでしてネットで調べてみても なかなか参考になるものはありません。 Perlの関数にpopen()が存在するのかまたfgets()、strtok()に類似する関数がありましたらアドバイスいただけないでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • popen使用時のエラー出力を出したくない

    popen( "コマンド", "r" ); このときコマンド実行時のエラー出力を出さないようにしたんですけど、 popen( "コマンド >& /dev/null", "r" ); とすると、 sh: /def/null: 番号が正しくありません。 となってしまいます。 これは、どういうエラーなんでしょうか? とにかく、プロンプトに余計なエラーを出したくないのですが、どうすれば消えるでしょうか?

  • 標準エラー出力の可否操作について

    unix-cプログラムにてpopen()等により実行した結果、 popen()の引数に設定したコマンドのパスが設定されていない場合 標準エラー出力をはいてしまいます。 close(2)を実行することにより出力はまぬがれるのですが、 他箇所の標準エラー出力は表示させたいためclose(2)では実現できません。 何かpopen()実行時の標準エラー出力をさせず処理を進める良い方法はありませんでしょうか

  • 引数で指定されたファイルを実行する

    実行する時に、引数としてファイル名を指定すると、そのファイルに書かれたスクリプトを実行してプログラムを終了する。 上記のようなCのプログラムを作りたいのですが、まったく見当がつかずに困っています。どうすればよいかご教授ください。

  • 他のコマンドの読み書き

    こんにちは。よろしくお願いします。 自分のプログラムから他のコマンドにデーターを渡したり 受け取ったりするにはどうすればよいのでしょうか? popen()だと"r"か"w"しか指定できないので読み込みも書き込みも したい場合に困ってしまいます。 ご存知の方がいらっしゃいましたらご教授お願いいたします。 C言語でOSはLinuxです。

  • 値を付けてタグからPHPを呼び出す方法を教えていただけないでしょうか

    お世話になっています。 HTMLタグで、1の部分をクリックしたら1の値を付けて(引数を指定して?)abc.phpを実行し、2の部分をクリックしたら2の値を付けて同じabc.phpを実行する…というようなプログラムを考えています。クラスを使わないで実現するにはどのようにしたらよろしいでしょうか。 初心者なものでよくわからず悩んでおります。 どなたかお助けいただけないでしょうか。 よろしくお願いいたします。

    • ベストアンサー
    • PHP