CGIから外部コマンド実行時の標準出力の取得方法について

このQ&Aのポイント
  • CGIから外部コマンドを実行する際、標準出力を取得する方法について説明します。
  • RH7.3の環境で試した結果、open関数やバッククォートを使用した方法ではエラーが発生しましたが、system関数を使用することで実行結果を出力できました。
  • 具体的には、CGIから呼び出す外部コマンドをsystem関数で実行し、その結果を標準出力に出力することで取得することができます。
回答を見る
  • ベストアンサー

CGIから外部コマンド実行時の標準出力の取得方法について

RH7.3の環境で試しているのですが、どうもうまく動作しません。 CGIから呼び出す方法として3つ試したのですが、 open(IN,"|sudo -u USER PROGRAM"); $text = `sudo -u USER PROGRAM`; system("sudo -u USER PROGRAM"); 最後のsytemは一応期待通りの動作になりました。 ただ、これですと実行結果(標準出力)を取り込めないのですが、何か方法はありませんか? PROGRAMはbashのシェルスクリプトです。 最初の2つですと、sudoの関係かエラーが出ます。 ./PROGRAM: SQL*Plus:: command not found systemの場合はちゃんと動作します。 ■実際にやりたいこと oracleサーバへの問い合わせ結果を取得したいのですが、 10gのクライアントまでは入りましたが、perlのDBD::Oracleがうまく入らなかったため、sqlplusで処理しようと考えています。 最初は直接CGIから呼び出そうとしたのですが、sudo時に環境変数が設定されないので、bashのシェルスクリプトにexportで先頭に書いております。 外部公開サーバではありませんので、とりあえずセキュリティーは無視しています。 systemで実行結果をcgiの標準入力に渡すか、バッククォートでエラーが出なくするかどちらかの方法はありませんでしょうか?

  • G-sun
  • お礼率33% (8/24)
  • Perl
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • maura
  • ベストアンサー率46% (48/104)
回答No.1

open(IN,"|sudo -u USER PROGRAM"); は、前にパイプがあるので標準入力を受け付けています。 標準出力を取得するには、 open(IN,"sudo -u USER PROGRAM|"); 後ろにパイプをつけてください。 そして、 print while(<IN>);

G-sun
質問者

お礼

間違っていた点が2カ所ありました。1つはご指摘の通り標準入力と出力の 指定の仕方を間違えていました。 もう1つは肝心のshellスクリプトに誤記があったようです。 bashでコマンドを実行する時に全体を`バッククォートでくくっていたの ですが、これがopenなどで実行しようとしたときに引っかかっていたよう です。 ただ、systemで実行した時には問題がなかったので、このあたりが原因を 追求するのにややこしくなっていました。 無事に解決できましたので、お礼とさせていただきます。 ありがとうございました。

関連するQ&A

  • [シェルスクリプト内で bashコマンド後のコマンドが実行されない]

    [シェルスクリプト内で bashコマンド後のコマンドが実行されない] 以下の様にシェルスクリプトを記述するとコマンド2が実行されません。 #! /bin/sh コマンド1 bash コマンド2 bash環境でコマンド2を実行させるにはどうしたら良いのでしょうか?

  • スクリプトを起動時に実行させるには

    バックアップ用の簡単なシェルスクリプトを書きました。 これを、システムの起動時と終了時に自動的に実行させたいのですが、 どこに置いたらいいのでしょうか。 とりあえず思い付いたのはbash_profileとbash_logoutに書くという方法ですが,できればログイン前,システム起動スクリプトが終わったあとあたりに実行させたいと思っています。 非常に初歩的な質問で申し訳ありませんが,どう調べていいかわからず困っておりますので,ごく大まかにお教え頂くかリンクなどを紹介していただければと思います。

  • sudoでのシェルスクリプト実行

    ユーザに、sudoで実行してもらいたいシェルスクリプトがあります。 sudoで実行しなかった場合、「sudoで実行してください」 というような警告文を表示し、処理を実行せずに終了し、 sudoで実行した場合のみ、処理を行ないたいです。 こうした動作を実現するには、シェルスクリプトに どういった記述を追記すればいいでしょうか? 環境はMacOSXです。よろしくお願いします。

  • killコマンド実行時のメッセージを出力させないためには?

    あるシェルスクリプトを実行させているところに、killコマンドを送り込むと、コンソールに「終了しました」と表示されてしまうのですが、これを表示させないようにすることはできますか??? kill 100 > 2>&1 > aaa.txtなどとしてもファイルに書き込まれないので、標準出力でも標準エラー出力でもないのでしょうか?

  • 別サーバーのcgiを実行させる

    あるサーバーで動作しているcgiスクリプトから、別のサーバーに置いてあるcgiスクリプトを実行させる方法はあるでしょうか? require 'http://…/…/test.cgi'; としても実行することは出来ませんでした。 googleで検索したところrequireではURL指定ができないと解説しているサイトがありましたので、requireを使わずに、(CGI.pm等の標準モジュール(?))なども使わないで他のサーバーに設置したcgiを動作させる方法があれば、教えていただきたいです。

    • ベストアンサー
    • CGI
  • 複数のCGIの実行結果の取得方法

    お世話になります。 掲示板への投稿の際、管理者審査が必要な掲示板を複数設置しています。 その際、各掲示板に投稿があったかどうかを管理者が確認する際に、掲示板の数だけ管理者としてログインし確認→別の掲示板へログインし確認→のループ作業が発生している状況です。 それらの作業をプログラムで一つの流れとして作れないものかと悩んでいます。 ちなみに現在は、最初の掲示板に管理者としてログインした際に、管理画面内でJSファイルから外部CGIを呼び出す形で <SCRIPT LANGUAGE=javascript src="./kanri.cgi"></SCRIPT> として各管理者用の掲示板を呼び出して、必要な部分の内容だけを出力するようにカスタマイズした状態で表示しています。(PASS等はクッキーで取得させています。) 上記のようにする事で掲示板の数だけ管理者としてログインしなくて済んでいるのですが、JSファイルで外部CGIの実行を70近く呼び出すようにしている為、表示される際の時間が物凄く遅いのがストレスに感じています。 これをプログラムで実現できればと思い、for文やwhile文、foreach文等の基本的動作についての解説を調べてはいるのですが、kanri1.cgi~kanri70.cgiまでのファイルの実行と、どのようにすればその結果を取得でき更に表示までできるのか・・など思うように調べられず悩んでいます。 ※シェルスクリプトでwgetで各kanri.cgi~kanri70.cgiの実行結果を取得し、その実行結果を >>でファイルに保存し表示するようにもしてみたのですが、結果的には表示までが非常に遅く、やってる事はJSファイルで呼び出しているのと何らかわりない事に気がつきました。) 実現の仕方は色々あるかと存じますが、諸先輩方、何か参考になるようなアドバイスやご教授など頂けませんでしょか。

    • ベストアンサー
    • CGI
  • CGIで外部コマンドを実行したときのエラーメッセージを取得したい

    PerlCGIで外部コマンドを実行して実行結果を取得する場合、パイプを利用して、 open(IN, "date |"); while (<IN>) { print $_; } close(IN); などとして結果の取得はできたのですが、 間違ったコマンドを指定した場合には、 エラーメッセージが取得できません。 たとえば、 $data などという間違ったコマンドを入力したときに、 bash: data: command not found という内容をCGIで取得したいのですが、 open(IN, "data |"); while (<IN>) { print $_; } close(IN); のような記述では取得できませんでした。 このようなエラー内容を取得する方法はありませんでしょうか? どうかよろしくお願いします。

    • ベストアンサー
    • CGI
  • シェルスクリプトで標準出力を捕捉

    お世話になります。 bashで作成したシェルスクリプトからjavaを実行して、標準出力にログが表示され続けるのですが、 このログから特定の文字列を捕捉して、その文字列が表示された場合に 実行を止めたいといった処理を行うにはどうすればよいのでしょうか。 ずっと流れ続ける標準出力から特定の文字列を捕捉できるかというのが質問になります。 パイプを使えば実現できるのでしょうか。 わかりにくい質問ですみませんがお願いいたします。

  • シェルスクリプトを実行後すぐに中断する方法

    シェルスクリプトがどのシェル(bash, zsh, tcsh)で実行されたかを確認したいため実行直後に停止したいのですが、どうすればよいでしょうか? すかさずctrl+zを押しても間に合いません。 (一般的な方法を知りたいのでスクリプト内でwaitというのは無しでお願いします。)

  • POSTメソッドで取得したデータをシェルスクリプトCGI経由でJava

    POSTメソッドで取得したデータをシェルスクリプトCGI経由でJava実行時の引数に渡す方法 HTML中級、Java、Unix系のシェルスクリプトに関して初級程度の知識があります。 Javaで書かれたプログラムを用いた、ブラウザ上で動作する CGIによるサーバサイド・アプリケーションを作ろうとしています。  http://d.hatena.ne.jp/shin/20090118/p1  http://d.hatena.ne.jp/Bayside/20050915  http://www.cs.adfa.edu.au/~gfreeman/CGIRequest.html 等のサイトを参考に、シェルスクリプトを用いたCGIを経由して サーバ上でJavaを実行し、その出力結果(シェルのechoやJavaのSystem.out.printlnによる) をHTMLとして受け取り、ブラウザ上で表示する所までうまくいきました。 上記のCGIに宛てて、別のHTML上の入力フォームからPOSTメソッドで文字列のデータを送信し、 その値をJavaに引数として渡してやりたいと考えています。  http://ameblo.jp/new3bon/entry-10210338319.html  http://waitwg.org/~pc-qa/?CMD=DCNT&CID=8 等から、POSTで送られたデータはシェルスクリプト上の標準入力に格納されると分かり、 #!/bin/bash echo cat cat >> ./ttt.txt URLエンコードされたパラメータを上記コードで表示させることまではできました。 また、コマンドラインからJavaを実行する際の引数は  http://www.02.246.ne.jp/~torutk/javahow2/commandline.html Java側のmainメソッドの引数として受け取れることは分かりました。 これらの方法を組み合わせて、CGIとしてJavaプログラムが実行される際に HTML上のフォームからPOSTメソッドで送信されたデータを渡してやりたいと考えています。 その際、シェルの標準入力に与えられたデータをシェルの変数に格納してやるか、  http://www.atmarkit.co.jp/flinux/rensai/shell03/shellstio.html に示されている標準入出力のすり替えを用いる等の方法ができないかと考えているのですが、 シェルスクリプトやJava上のどの段階で、どのようなコードを書けばいいのか分からずにいます。 (下記コードでは、各種パスを通す際に標準入出力の中身が書き換えられる前らしいと見当はついているのですが……) 複数の要素が込み入って複雑なことになっていますが、 解決方法をご存知の方がおられましたら、ご教唆のほど願います。 下に書きかけのシェルスクリプトのコードを書いておきます。 #!/bin/sh JAVA_HOME=/usr/java/jdk1.6.0_20 PATH=$PATH:$JAVA_HOME/bin CLASSPATH=.:$JAVA_HOME/lib/mysql-connector-java-5.1.12-bin.jar export JAVA_HOME PATH CLASSPATH /usr/java/jdk1.6.0_20/bin/java \  (中略) Main