プロが教える店舗&オフィスのセキュリティ対策術

perlのsystem関数内で変数展開について困っています。変数展開はできるのですが、その変数の後に':'(コロン)をつける必要があるのですが、それがモディファイアとして認識されてしまうようです。コロンをそのままperlに評価させずにsystem(shell)に渡す方法はないでしょうか?

$host = "xxxx.com";
system("program ${host}:22");

ちなみに、$host:22ではうまく変数展開されないそうで、{}を使うまでは良かったのですが、その後のコロンでつまっています。programの都合でhost、コロン、ポート番号を渡す仕様のため変更できません。よろしくお願いします。

A 回答 (3件)

「シェルのモディファイア」で変換されてしまう、という話なら、Perlは直接関係ありません。


方法として
・シェルで変換しないようなコマンドラインを、system関数に渡す
# ただ、 xxxx.com:22 をなんかに変換してしまうようなシェル、というものに思い当るものがありません。

・引数をリストにしてsystemを実行することで、シェルを通さないで実行する
system('program', "${host}:22") ;
http://perldoc.jp/func/system
http://perldoc.jp/func/exec

これでだめなら、別の問題でしょう。
# $hostの後ろに空白とか改行コードとかが付いてるとか

ちなみに、コマンドラインシェルから program xxxx.com:22 を実行したらちゃんと動作するのですか?
    • good
    • 0
この回答へのお礼

// まちがって別のにリプライをつけてしまいました。正しくはこちらです。

遅くなりましたが、元のスクリプトを分離してテストケースを作成しました。programは実際にはstoneというものです。

さて、コマンドラインからは実行できます。

$ stone `cat ~/remotehostname`:22 1026 -> OK
$ stone stone $remotehostname:22 1026 -> OK

これは自ホストのポート1026に来たパケットをリモートの22にフォワードするもので、両方共動作しました。
これが動作したということはシェルのモディファイアじゃないですね。これもシェルが評価しているんだし。

さて、以下のテストケースを実行すると、

#! /usr/bin/perl
$remotehostname = `cat ~/remotehostname`;
system("stone ${remotehostname}:22 1026");

Invalid <host>:<port>: 048.112137072.m-net.ne.jp
sh: line 2: :22: command not found

このようにホストの後に改行があって:22というコマンドが無いと出ます。これを見てモディファイアかと誤解したのですが、どうもそうではなく、ご指摘のようにホスト名の後の改行を誤って(正しく?)認識しているようです。

であれば、簡単で

chop($remotehostname);

これを挿入することで正しく動作することができました。ありがとうございました。ホスト名の後の改行が大きなヒントでした。

お礼日時:2013/01/17 19:44

もちろんそれでいいわけですが....>#1



ただ, 実際試すとこの場合コロンは全く悪さをしないんですよ. 例えば
use feature 'say';
$host = "example.com";
say "$host:22";
では (想定通り) example.com:22 が出力されるんですな.

「モディファイア」ってなんだろう.
    • good
    • 0
この回答へのお礼

遅くなりましたが、元のスクリプトを分離してテストケースを作成しました。programは実際にはstoneというものです。

さて、コマンドラインからは実行できます。

$ stone `cat ~/remotehostname`:22 1026 -> OK
$ stone stone $remotehostname:22 1026 -> OK

これは自ホストのポート1026に来たパケットをリモートの22にフォワードするもので、両方共動作しました。
これが動作したということはシェルのモディファイアじゃないですね。これもシェルが評価しているんだし。

さて、以下のテストケースを実行すると、

#! /usr/bin/perl
$remotehostname = `cat ~/remotehostname`;
system("stone ${remotehostname}:22 1026");

Invalid <host>:<port>: 048.112137072.m-net.ne.jp
sh: line 2: :22: command not found

このようにホストの後に改行があって:22というコマンドが無いと出ます。これを見てモディファイアかと誤解したのですが、どうもそうではなく、ご指摘のようにホスト名の後の改行を誤って(正しく?)認識しているようです。

であれば、簡単で

chop($remotehostname);

これを挿入することで正しく動作することができました。ありがとうございました。ホスト名の後の改行が大きなヒントでした。

お礼日時:2013/01/17 19:42

system('program ' . $host . ':22') ;


とかは?
    • good
    • 0
この回答へのお礼

回答がついたメールを見落としていたのか気づきませんで、返事が遅くなりました。これもやってみたのですが、だめでした。今休みで試せないので、後でやってみます。だめな理由はperl->shellと渡すさいにshellでモディファイアとして評価されたからです。

お礼日時:2013/01/01 10:32

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