Perlのsystem関数で変数展開後にコロンを渡す方法について

このQ&Aのポイント
  • Perlのsystem関数内で変数展開について困っています。変数展開はできるのですが、その変数の後に':'(コロン)をつける必要があるのですが、それがモディファイアとして認識されてしまうようです。
  • コロンをそのままperlに評価させずにsystem(shell)に渡す方法はないでしょうか? $host = "xxxx.com"; system("program ${host}:22");ちなみに、$host:22ではうまく変数展開されないそうで、{}を使うまでは良かったのですが、その後のコロンでつまっています。programの都合でhost、コロン、ポート番号を渡す仕様のため変更できません。
  • Perlのsystem関数内で変数展開後にコロンを渡す方法が知りたいです。変数展開はできるのですが、コロンを直接渡すとモディファイアとして認識されてしまいます。programの仕様でhost、コロン、ポート番号をそのまま渡す必要があるため、解決策を教えてください。
回答を見る
  • ベストアンサー

perlのsystem関数内でのコロンについて

perlのsystem関数内で変数展開について困っています。変数展開はできるのですが、その変数の後に':'(コロン)をつける必要があるのですが、それがモディファイアとして認識されてしまうようです。コロンをそのままperlに評価させずにsystem(shell)に渡す方法はないでしょうか? $host = "xxxx.com"; system("program ${host}:22"); ちなみに、$host:22ではうまく変数展開されないそうで、{}を使うまでは良かったのですが、その後のコロンでつまっています。programの都合でhost、コロン、ポート番号を渡す仕様のため変更できません。よろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.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 を実行したらちゃんと動作するのですか?

moca89
質問者

お礼

// まちがって別のにリプライをつけてしまいました。正しくはこちらです。 遅くなりましたが、元のスクリプトを分離してテストケースを作成しました。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); これを挿入することで正しく動作することができました。ありがとうございました。ホスト名の後の改行が大きなヒントでした。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

もちろんそれでいいわけですが....>#1 ただ, 実際試すとこの場合コロンは全く悪さをしないんですよ. 例えば use feature 'say'; $host = "example.com"; say "$host:22"; では (想定通り) example.com:22 が出力されるんですな. 「モディファイア」ってなんだろう.

moca89
質問者

お礼

遅くなりましたが、元のスクリプトを分離してテストケースを作成しました。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); これを挿入することで正しく動作することができました。ありがとうございました。ホスト名の後の改行が大きなヒントでした。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

system('program ' . $host . ':22') ; とかは?

moca89
質問者

お礼

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

関連するQ&A

  • perlによるシステム上の任意のプログラム実行

    Perl初心者です。 システム上の任意のプログラムを実行しようと考えています。system関数のように呼び出し元に戻っては欲しいのですが、プログラム完了までwaitしないようにしたいのです。何か良い方法はあるのでしょうか。是非、ご教授いただきたく存じます。

  • system関数でatコマンドを呼び出して使用したいのですが

    はじめまして、system関数について質問があります。 TVキャプチャが動作しているマシンがありまして(OSはFedoraCore6) そこでperlでCGIを作成して、その中で予約録画みたいなことがやり たいのですが、CGI中にsystem関数でatコマンドを利用して予約をして みたのですが、うまく動作しません。 $1 = 10; $2 = 20; system(`echo "xxxx.sh"|at $1:$2`); (xxxx.shはmencoderを起動するシェルスクリプト) みたいにしているのですが、atqなどで確認しても予約されていません。 どのようにしたらsystem関数からatコマンドが利用できるのでしょうか? ご教授よろしくお願いします。

  • smbclientの戻り値を取得

    お世話になります。perlプログラムからshellを呼び出して shellでsmbclientを呼び出すのですが、smbclientの戻り値を 受け取るにはどうしたらよいでしょうか? test1.pl $re = system "sh test1.sh"; test.sh smbclient //host/dir -U user%passwd put ... put ... exit イメージはこんな感じです。 宜しくお願いします。

  • Perlで変数に代入された文字の置き換えを行いたい

    Perlで、変数Aに代入された文字を変換し、変数Bに代入するプログラムを作りたいと思っています。 具体的には、「北海道」が変数Aに代入されると、「hokkaido」を変数Bに代入するというものです。 これを47都道府県全体でやりたいと思っています。 プログラムの都合上、 北海道 → 変数A → hokkaido → 変数B という流れで変換する必要があります。 具体的なソースを何卒ご教示いただければ幸いです。 お手数をお掛けいたしますが、アドバイスのほど、よろしくお願い致します。

    • ベストアンサー
    • Perl
  • perlプログラムが動かない

    パールのプログラムを作成して拡張子「.pl」で保存するとアイコンがパールのマークになりますよね。 プログラムファイルにデータファイルをドラッグすると、プログラムファイル(拡張子.pl)のアイコンが白黒反転して、目的の加工データをファイルとして出力するプログラムがるのですが、プログラムを作成したパソコンともう一台しか動作しません。他のパソコンでは、プログラムファイルにデータファイルをドラッグしても、プログラムファイル(拡張子.pl)のアイコンが白黒反転せず、パールプログラムが動作しません。 どこの設定をどのように変更すればいいのでしょうか。(プログラムファイルのアイコンを白黒反転させるにはどうしたらいいのでしょうか。) コマンドプロンプトでパスが通っているか確認をしたのですが、どのパソコンもパスは通っています。 プログラムの動作するパソコンの「システム環境変数のpathとPATHEXT」をプログラムの動作しないパソコンにコピーペーストしてもNGでした。 ※perl.exeが入っているディレクトリは同じにしています。プログラムファイとデータファイルをperlフォルダに入れても駄目でした。  OSは、Windows XPです。

  • perlのシングルクォートとダブルクォートの置き換えについて

    perlのシングルクォートとダブルクォートの置き換えについて お世話になります。 現在、perlにて開発を行っているのですが、一つ問題に当たってしまいました。問題になっているのは、文字列を扱う部分です。perlにおいて文字列はシングルクォートに囲まれたものと、ダブルクォートに囲まれたものがあると思うのですが、この両者の違いは、内部に書かれた変数等を展開するか否かだったと思います。 実は開発の途中でこのシングルクォートで囲まれた文字列を、ダブルクォートに囲まれた文字列に変更しなければいけなくなりました。つまり $test = 'aaa';  を  $test = "aaa"; としたいのです。これってperlの仕様的に可能なのでしょうか? かなり悩んだのですが、どうしてもわかりませんでした。 ちなみに、なぜこの処理が必要なのかというと、HPの製作をしているのですが、設置したフォームからその内容を得るというプログラムを書いた際に、そのフォームの内容がシングルクォートでしか得られないからです。シングルだとそののちの処理に影響が出てしまうのです。 だれかご存じないでしょうか。よろしくおねがいします。

    • ベストアンサー
    • Perl
  • Perl から csh 実行

    やまとです。 いつもありがとうございます。 Perl + csh を同時(?)に実行する方法を教えてください。 OSはSunです。 具体的にどのような処理を行いたいか簡単に説明しますと。 1.Perlでcshを実行(system関数?)し、cshで環境変数をセット(source)する。 2.cshで環境変数をセットしたら、ファイルを出力する処理が行われます。 3.Perlでcshによって出力されたファイルの内容を画面に表示します。 以下ソースを掲載します。(抜粋して) ================================================== = Perl ( test_perl.pl ) $data = "ABC"; $ret = system(`test_csh.sh $data`); ・ ・ ファイル(test.log)を開き、読込、画面に表示します(まだ作成してません。) ================================================== = Csh ( test_csh.sh ) source test_source.sh echo $1 > test.log ================================================== = test_source.sh setenv CLASSPATH .:/aaa・・・・・・ ↑ PATHの設定を行ってます。 ================================================== 画面に、「ABC」と出力させたいのです。 Perlからcshが実行されていないように思えるのですが、 Perlのsystem関数の使い方が誤っているのでしょうか? それとも、ClassPath等の設定をしなければならないのでしょうか? ちなみにコマンドから、 # test_csh.sh ABC と実行しますと、ファイルが出力され、かつ、sourceも実行されています。 Perlから実行する方法を教えてください。 説明が不十分であれば、補足いたしますのでご指摘ください。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • perl から ncftpを使う場合にエラー

    お世話になっております。 perlスクリプト中でncftpgetを使って、FTPサーバーからファイルをダウンロードするスクリプトを作成しております。 ところがshellでは問題なくいくのですが、perlでは上手くいきません。 <ソースコード> ※$DATE以外は文字列 ※$DATE = `date +%Y_%m_%d`; system "ncftpget -u $USER -p $PASS -a -t 15 -e $WORK_PATH/logfile_$DATE -d $WORK_PATH/logfile_ncftp_$DATE $ADDRESS /tmp /tmp/$FILE 2>> $WORK_PATH/logfile_$DATE 1>/dev/null"; perl -wc ではOKです。 perl -d で行うと、ncftpgetのUsages等(オプションミス等の時に表示されるものです)が表示されてしまい、その後、「-d: 見つかりません。」となってしまいます。 また、上記ソースコードをshellスクリプトでそのまま書き直すと、正常に動きます。 加えて、$DATEのみ適当な文字列(1111や2222)等にすると、問題なく動作します。 $DATEに値が入っていないのか思ったのですが、system関数前後で標準出力させてみると、正常に表示されてます。 $DATE部分に日付を入れたいので、固定にするわけにはいかないですし……。 何故perlだと上手くいかないのでしょうか?

    • ベストアンサー
    • Perl
  • C言語のプログラム中に使うsystem()関数に変数を使う場合

    C言語のプログラム中に使うsystem()関数に変数を使う場合 system("sort < a.txt |uniq >aa.txt"); という関数を使うと テキストファイル a.txt は編集(sort,uniqにより)され aa.txt となるのですが このファイル名を変数として扱いたいので char str[255]; for(z=0; z<255; z++){ sprintf(str,"sort < %d.txt |uniq >0%d.txt", z, z); system(str); } という形にすると 0.txt → 00.txt 1.txt → 01.txt と255.txtまで編集されると思ったのですが 編集後のファイルが白紙で現れてしまいます。 system("sort < a.txt |uniq >aa.txt"); のファイル名に変数を扱い 複数のファイルの編集をするためには どのようなプログラムを作成すると良いのでしょうか? ご回答よろしくお願いいたします。

  • VB6.0でシステム環境変数PATHへ、%XXX%設定後、ログオフ以外で反映する方法について

    1.OS Windows2000 Professional SP4 2.プログラム VB6.0 3.質問内容   システム環境変数を登録後、ログアウトなしで、反映できない。   MS文書番号104011で、SendMessageTimeoutで、変更を通知しても   %XXXX%で、PATHに追加登録した内容が展開されない。   なお、regedt32.exeで、%XXXX%は、REG_EXPAND_SZで登録を確認 4.事象 1)登録内容   プログラムにて、システム環境変数に以下登録    A=C:\tmp    <= 新規     AA=%A%\work  <= 新規     PATH=現状項目;%A%\tmpi   <= 既存へ追加 2)プログラム実施結果    コマンドプロンプトで、確認を行うと、    AA=C:\tmp\work に、展開されているが、    PATH=現状項目;%A%\tmpi     と、展開されていない。また、この状態で、C:\tmp\tmpi に、    バッチを作成しC:\から、起動しても、PATHが通っていないため、    「プログラムが見つからない」というエラーがでます。    また、SendMessageTimeoutで、通知しても、コマンドプロンプトから    PATHを確認しても、PATH=現状項目;%A%\tmpi  となり、展開    されていない。   3)リブートすると、展開されるようです。     ※regedt32で、確認すると、PATHには、現状項目;%A%\tmpi で       登録されています。 5.疑問  リブートせずに、通知させる方法はないでしょうか?  特に、新規に登録したシステム環境変数はOKで、追加で登録したPATHに  反映できないのは、なぜでしょうか? 以上 アドバイスのほど、よろしくお願いします。

専門家に質問してみよう