AKB48の推しメンをセンターにできちゃうかもしれない!? >>

Perlのプログラム内部で保持している変数の値をシェルコマンドに与える方法はありますか?

$value=12345;
や、
@array=('ONE', 'TWO', 'THREE');
などの変数の値を外部コマンド(標準入力を受けることができるコマンド)に渡したいのです。

方法がわからないので、現在は一度ファイルに書き出して、
system('cat file.name | command');
のようにして渡しています。なんか賢くない書き方のような気がするのですが。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

open関数で、commandへの出力をファイルとして開けば


いいのではないでしょうか。

open(MYCMD, "| /your/command");
print MYCMD $value;

この回答への補足

ありがとうございます。

それでは、標準入力で受けて標準出力に書き出す外部コマンドがあり,Perl内部でそれを利用したい場合、

open(FILE, "| /my/command |");
print FILE $value; # commandへの入力
while(<FILE>){
# commandの出力を利用
}

でファイルと同じように扱えますか?試したところどうもうまくいかないのですが。

補足日時:2004/05/10 16:00
    • good
    • 0
この回答へのお礼

入力側のパイプと出力側のパイプは同時には使えないという記述を見つけました。こういうことを実現したい場合、普通どうするんでしょうか?

お礼日時:2004/05/10 16:07

> system('cat file.name | command');



こうするくらいなら、こうのほうがましかも。
system("command $value");
# or `command $value`

ただし、どれも汚れた値は扱えない。
(open & printだとどうなんだろう?sh使ってないからok?)

>open(FILE, "| /my/command |");

perlipc(Perl のプロセス間通信)の日本語訳を参考URLに上げておきます。
(双方向通信はやったこと無いけど、socketpairが無難なのかな?)

参考URL:http://www.kt.rim.or.jp/~kbk/perl5.005/perlipc.h …
    • good
    • 0
この回答へのお礼

ありがとうございます。
やろうとしていたことがプロセス間の通信にあたり、まさにそのことを記述したドキュメントが存在するということすらわかっていなかったので、助かりました。

これから勉強してみます。

お礼日時:2004/05/11 08:24

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

QPerlで行頭にある文字が含まれている行を全部削除して詰めたい

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

#!/usr/bin/perl ;
open(IN, "test.doc") or die ;

open(OUT, ">testout.doc");

while(<IN>) {
chomp ;
if (/(\S+)/) {

$name = $1 ;

if ($name =~ /^test112(\S+)/) {
#ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが

;

}
print OUT " \n" ;
}
}
close (IN) ;
close (OUT) ;

大変困っております。宜しくお願いします。

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

...続きを読む

Aベストアンサー

一致しなかったときのみ出力するということで、

while(<IN>){
unless(/^test112/){
print OUT;
}
}

更に簡単に書くと、
while(<IN>){
print OUT unless(/^test112/);
}
となります。

削除にこだわるなら、
while(<IN>){
s/^test112\s.+//;
print OUT;
}
あたりでしょうか。

もしくは、明示的に削除したいなら、
while(<IN>){
if(/^test112\s.+/){
$_ = "";
}
print OUT;
}
というふうに、カラの文字列を代入してやるのも、値を削除するときの常套手段ですね。

QUse of uninitialized value ---

初心者です。フォームに文字を入力してもらい、↓
print blockquote(
textfield(
-name => 'die Antwort',
省略----条件にあえば、
my $value = param('die Antwort');#として
if (($value eq $ans || $value eq $ans2) and ($c eq $num)){
「正解」と表示することにしました。すると、うまくいくのですが、
if (($value eq $ans || $value eq $ans2) and ($c eq $num)){
について「Use of uninitialized value ----」とApacheのerror logに書かれてしまいます。このためerror logがすぐに巨大なファイルになってしまいます。これを避ける方法をお教えください。よろしく、お願いいたします。

Aベストアンサー

コードに use warnings が入っているのですよね。
デバッグも済んでいるのでしたら、
no warnings qw ( uninitialized );
で、この警告の表示を抑制してもよいと思います。

QPerlで変数を使用した置換ができない

ファイル内の「1 2 3 4 5」などの数字の箇所を、「1回 2回 3回 4回 5回」のように、「回」をつけた形に変えることを考えています。
以下のようなスクリプトを書きましたが、うまくいきません。

# 「$search_replace」の参照先のテキストファイルの内容
(\d) タブ記号 $1回


EOF

# 問題のスクリプト(一部)
chomp($search_replace);
(my $search, my $replace) = split(/\t/, $search_replace);
$string[$i+1] =~ s/$search/$replace/g; #ここが問題と思われる箇所

ほしい結果は右のとおり。「1回 2回 3回 4回 5回」
現実の結果は右のとおり。「$1回 $1回 $1回 $1回 $1回」

置換文字列の$1の部分がうまく展開(?)できないようです。
どうすればよいか、ご教示ください。

Aベストアンサー

正規表現の置換部はダブルクォート文字列と同様に評価されるので、次の2つの文は同じように機能します。質問のケースでは、変数を2重に置き換えなければならないので、明示的にダブルクォートが必要になります。

$string[$i+1] =~ s/$search/$1回/g;
$string[$i+1] =~ s/$search/"$1回"/eg;

QPerlで環境変数を設定するには

あるPathを環境変数として設定したい場合、
例)TNS_ADMIN=D:\Test\exe

たとえばMS-DOSなら、
set TNS_ADMIN=D:\Test\exe
と設定しますよね。

これと同じことをPerlでどうやればいいのかというのが質問です。

ENVモジュールを使って、
$ENV{TNS_ADMIN}=D:\Test\exe
としてみたものの、Perlを実行した後に確認してみるとセットされていないようでした。
(確認方法はPerlを実行したDOSプロンプトにて"set"を実行)

よろしくお願いします。

Aベストアンサー

>>破棄された後に確認しても、わかりません。
>どうにかその環境変数がセットされていることを確認する方法ってないのでしょうか?

perlで子プロセスを起動すれば確認できます。

例えば、NT系のOSであれば...

次のスクリプトを用意。
#!c:\perl\bin\perl.exe
$ENV{"TNS_ADMIN"}="D:\\Test\\exe";
system("cmd");

それを実行すると、コマンドプロセッサが表示されるので、
set[return]
すれば、子プロセスの環境変数が確認できます。
確認後、exit[return]すると、子プロセスが終了するので、
親プロセスたるperlも終了する。

Qperlスクリプト内でシェルコマンドを実行するには??

タイトル通りなのですが、perlスクリプト内でシェルコマンドを実行させる方法が分からなく、困っています。

実行したいシェルコマンドはUNIXのcrontab なのですが・・。

また、perlスクリプト内以外でシェルコマンドを実行する方法はあるのでしょうか??

どなたか分かる方いらっしゃいましたらご教授いただけると幸いです。よろしくお願いします。

Aベストアンサー

system() 関数とバッククォート(`...`の形式)と open() による方法、それと fork 後に子プロセスで exec する方法があります(但しこれはUNIX系OS以外では正常動作するかどうか分かりません)。

system() 関数を使う場合はコマンドラインから打ったのとほぼ同じです。バッククォートの場合はそのコマンドが標準出力に出力した内容を文字列として受け取れます(これはUNIX系OSでよく使われるシェルの動作とほぼ同じということです)。open() でやる場合はコマンドに対する標準入力を与えるか、またはコマンドからの標準入力を受け取れます。これは open(FP, '| command arg ...') または open(FP, 'command arg ... |') のように最初か最後に | を入れてオープンし、その後それに対して print するか <FP> のような方法で読むかします。fork(), exec() の場合はその後の入出力の接続は(pipe()と組み合わせて使うなどして) 自由に行なえます。

で、やることが crontab への設定ということならば open 使った方法が楽なんじゃないでしょうか。但し crontab -l をやった後に crontab で追加する場合はその間に他のプロセスが編集をしてしまうかも知れないので注意が必要です。(全部書き変えていいなら open(F, '| crontab'); でオープンして print F ...; でただ書いてしまえばいいと思いますが)

system() 関数とバッククォート(`...`の形式)と open() による方法、それと fork 後に子プロセスで exec する方法があります(但しこれはUNIX系OS以外では正常動作するかどうか分かりません)。

system() 関数を使う場合はコマンドラインから打ったのとほぼ同じです。バッククォートの場合はそのコマンドが標準出力に出力した内容を文字列として受け取れます(これはUNIX系OSでよく使われるシェルの動作とほぼ同じということです)。open() でやる場合はコマンドに対する標準入力を与えるか、またはコマンドからの...続きを読む

Q現在のディレクトリパスを取得するには!?

perlにて現在のディレクトリパスを取得するにはどのようにすればいいのでしょうか?
モジュールをつかってcwd()で取得できるようなのですが、モジュールが入っていないサーバでも動くようにしたいのですがうまくできません・・・
どなたかご存知でしたら教えてください。

Aベストアンサー

if($^O eq "MSWin32"){
$cwd=`cd`;
} else {
$cwd=`pwd`;
}
print $cwd;
--------------
ぐらいでいいんじゃないでしょうか

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

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の標準入力に渡すか、バッククォートでエラーが出なくするかどちらかの方法はありませんでしょうか?

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
sys...続きを読む

Aベストアンサー

open(IN,"|sudo -u USER PROGRAM");
は、前にパイプがあるので標準入力を受け付けています。

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

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qsystem から得た情報を変数に入れる方法

system から得た情報を変数に入れるには、どうしたらよいでしょうか。

$ls = system("ls -l");
これをスクリプトの中に置いてコマンドライン上から実行すると、そのまま、lsの結果が表示されてしまいました。

$ls は 0 を返します。

どうしたらよいのでしょうか。

Aベストアンサー

OS環境が書かれていないのでちょっと自信ありませんが、
Windows 用の ActivePerl と Jperl で確認しました。
----------
system() を使わずに、
  $ls = `ls -l`; (←逆シングルクオートで囲む)
というのはどうでしょう?
これで、ls -l の結果を $ls に入れることができます。

ただし、最後の改行もそのまま入ってくるので、これを取り除きたい
場合は、
  chop ($ls = `ls -l`);
とすれば、うまくいきます。

コマンド実行の結果(正常/異常)も知りたい場合は、
この後で $? 変数を参照すればいいでしょう。試しに

  chop ($ls = `ls -l`);    ←パスをいろいろ変えてみて…
  print "---\n",$ls,"---\n";
  print "Status $?\n";

で、やってみて下さい。


人気Q&Aランキング