CGIに関する質問

perl

人気の記事:

コメント

  1. 頼人[yori] より:

    hogeのpathの問題だったりしませんか

  2. ゆうすけ より:

    予め『local $/ = undef;』が必要かと。

    単に『$c = <HOGE>;』だけだと1行だけしか取り込まれないか、

    または全体の行数だけしか取り出せなさそう。

  3. KAIN より:

    $c = `hoge $a $b`;

    # hoge $a $bの実行結果の出力を$cへ。

    hogeはCGIにおける実行権限の範囲にいるかどうか、telnetで動いてもCGIの実行権限では見えない範囲のコマンドでないかを確認。

    できれば頼人[yori] さんの指摘どおりパスの確認をする。

    Cのプログラムhogeの記述はルートからのフルパスがオススメ。

  4. Gackt より:

    ありがとうございます。

    他の人にもわかるように書き直すと、perlで書いたCGIプログラムの中で「コマンドにデータを渡して読み取る」ことをしたいんです。ここでは、コマンドとは、C言語で書かれたプログラムのことをさしていて、hogeは、gcc -o hoge hoge.cによりコマンドのように使用できるようにしています。

    今回は、1行だけを取り出したいんです。>ゆうすけさん

    /home/httpd/cgi-bin/hogeにしてもだめなんです。owner, groupをapacheにして、パーミッションも755に設定してるんですが。>yoriさん, KAINさん

    perlでは、コマンドに変数を渡すことがサポートされていないようです。つまり、次のようにはできないみたいです。

    open(IN,”| hoge $a $b |”);

    $c = <IN>;

    close(IN);

    そこで、

    use IPC::Open2;

    $c = open2(*READ, *WRITE, “/home/httpd/cgi-bin/hoge”);

    print WRITE “$a $b”;

    close(WRITE);

    $c = <READ>;

    にしてみたんですが、これもサポートされていないようです。

    素人質問ですみませんが、よろしくお願いします。

  5. とおる。 より:

    一般的には「コマンドに変数を渡すこと」はできるようですよ。

    ↓このコマンドは正常に動きました。

    perl -w -Mstrict -e ‘open(FH,”ls -l -t |”) or die;print <FH>;’

    あと、「うまくいきません」というのは、エラーが出るのでしょうか? あるいは、なにも出てこないということでしょうか?

    use strict;

    use warnings;

    していますか?

    hoge 単体でコマンドラインで呼び出す場合は動作しますか?

    $a や $b の中身は正しいですか?

  6. Gackt より:

    torusさん。お返事ありがとうございます。

    > あと、「うまくいきません」というのは、エラーが出るので

    > しょうか? あるいは、なにも出てこないということでしょ

    > うか?

    エラーメッセージも含めて、何も表示されません。

    > use strict;

    > use warnings;

    > していますか?

    はい。それでも駄目でした。

    > hoge 単体でコマンドラインで呼び出す場合は動作しますか?

    はい。動作しています。

    % sample.cgi

    では、ちゃんと動作するのですが、htmlからcgiの値を呼び出した場合は動作していないようです。

    つまり、

    sample.cgi -> 表示される。

    html -> sample.cgi -> 何も表示されない。

    > $a や $b の中身は正しいですか?

    はい。変数の方は問題ないようです。

    パーティションを755にして、ownerとgroupをapache

    にしているのですが、この辺に問題があるのでしょうか?

  7. KAIN より:

    ・printし忘れをチェック。

    ・HTTPヘッダーのチェック。

    ・ヘッダー後の改行2発をチェック。

    ※この書き方だとヘッダーが怪しい。

    > はい。動作しています。

    > % sample.cgi

    > では、ちゃんと動作するのですが、htmlからcgiの値を呼び出した場合は動作していないようです。

    >

    > つまり、

    >

    > sample.cgi -> 表示される。

    > html -> sample.cgi -> 何も表示されない。

    これだと、ターミナル上では動くがデーモン上で動かないと言ってるっぽい(% あたりが)

    だとするとHTTPDでperlのCGIが表示されるためのヘッダーを書き忘れている可能性もある。

    ってのは考え過ぎか。

  8. KAIN より:

    htmlからcgiの値を呼び出した場合のステータスコードが500とかもあるとわかりやすいんだか・・・

    書くのも恥ずかしいくらい釈迦に説法なんですが、

    投稿の補完。

    HTTPDで出力テストするときは以下のサブルーチンをどっかにかいとく。

    ちゃんと動いたらまじめにコーディングする。

    BEGIN{

    # HTTPDでのヘッダー出力

    print “Cache-Control: no-cache\n”;

    print “Pragma: no-cache\n”;

    print “Expires: 0;\n”;

    print “Content-type: text/html;charset=Shift_JIS\n\n”;

    }

    # Shift_JISかどうかは各自注意。

  9. とおる。 より:

    cgi をコマンドラインで動かして動くということは、やはりパーミッションやパスが怪しいですね。CGI が呼び出されるときに chroot されている可能性もありますし。

    open の行を

    open(HOGE,”hoge $a $b |”) or die $!;

    として、oepn が失敗したときにエラーで終了するようにすると何かヒントが得られるかもしれませんよ。

    ユーザ名やグループ名も環境によって違うと思いますので、その確認も必要かも。apache:apache じゃなくて nobody:nogroup だったりとか。

  10. Gackt より:

    KAINさん。お返事ありがとうございます。

    説明をさせていただきますと、

    1 htmlから、単語1と単語2を入力する。

    2 sample.cgiを呼び出す。$a=単語1 $b=単語2

    3 sample.cgiの中で、$c = `/home/httpd/cgi-bin/hoge $a $b`;

    4 htmlで、$a $b $cを表示する。

    この過程で、

    4 $aと$bはちゃんと表示させられるが、$cが何も表示されません。しかし、sample.cgiのみで実行させると$cも表示できます。

    よろしくお願いいたします。

  11. らいあ より:

    こんにちわ。

    動的に作成したサブルーチンを、ファイルかどこかに保存し

    ておいて、あとで読み込んで実行することはできませんか?

  12. Uricle より:

    サンプルを書いてみました。

    #! /usr/local/bin/perl

    use strict;

    print “Content-Type:text/html\n\n”;

    my $a = ‘-m’;

    my $cmd = ‘/bin/uname’;

    my $c = undef;

    open INPUT, “$cmd $a|” or die “couldn’t open command ‘$cmd’\n”;

    $c = <INPUT>;

    close INPUT;

    print “$cmd $a<br>\n”;

    print “$c<br>\n”;

    —-

    コマンドラインでの実験結果(環境によりi686の部分は変わる可能性があります)

    Content-Type:text/html

    /bin/uname -m<br>

    i686

    <br>

    —-

    http経由での実験結果:

    /bin/uname -m

    i686

    —-

    というようになりましたが、何か参考になりますか?

    それとも上記サンプルでもうまく動きませんでしょうか

  13. 頼人[yori] より:

    > 2 sample.cgiを呼び出す。$a=単語1 $b=単語2

    これが少し気になったんですが、$aや$bの値はマルチバイト文字を含みますか?

    > 3 sample.cgiの中で、$c = `/home/httpd/cgi-bin/hoge $a $b`;

    のbacktickの所でshellが起動されるのでshellの環境によって挙動が変わってきます。

    実行するユーザによってshellが違い、そのせいで日本語の引数が渡るかどうかも変わる…という症状を見たことがあります。

    —————–

    本題と外れますが、

    > 2 sample.cgiを呼び出す。$a=単語1 $b=単語2

    > 3 sample.cgiの中で、$c = `/home/httpd/cgi-bin/hoge $a $b`;

    いきなりこれだと危ないです。HTMLから$aに”;/bin/rm -rf *”とか突っ込むと実行されてしまいます。

  14. KAIN より:

    権限きてないっぽいに一票。

    頼人[yori] さんが指摘された状態、…引き数をフォームから受け取ってsystemとかで実行されないように通常いらないものがexecできないように設定されているはず。

    まずは、たいてい許可されているpwdかなんかで実験してみるとか。

  15. KAIN より:

    HTTPD経由で権限きているか

    ファイルテスト演算子でチェック用のCGI書いてみるとか。

    $cmdz=’/hoge/hoge/bahi’;

    print “$cmdz は実行できねぇんじゃボケェ!\n” unless(-x $cmdz);

  16. Gackt より:

    Uricleさん、頼人[yori]さん、KAINさん、いろいろ教えてくださってありがとうございます。

    Uricleさん、サンプルありがとうございます。

    >いきなりこれだと危ないです。HTMLから$aに”;/bin/rm -rf >*”とか突っ込むと実行されてしまいます。

    頼人さん、KAINさん、アドバイスありがとうございます。対応しました。

    原因は、パーミッションでした。Cプログラムに辞書を読み込んでいるのですが、辞書のパーミッションを変更していなかったためにうまく動作しないことがわかりました。

    みなさん、ほんとうにありがとうございました。

  17. KAIN より:

    お疲れ様でした。

    辞書の権限でしたか。

    デバックはいい経験です。参考になりました。

    ぼくを教えてくれた人は「躓くってのは良いことだ。進んでいる証拠だからね。なにも自分でしない人は躓きもしない」とよく言ってました。

    頑張ってください。