Perl:コマンドライン引数でつまずく

さっきまでPerlのスクリプトと格闘していてやっと問題が解決(?)したので、
対処方法をメモしておきます。でも、まさかこんなことが起き得るんですね~。

さて、その問題とはコマンドライン引数に改行文字が含まれるという問題。
簡単にどんなシチュエーションでこの問題が起こったかを説明します。

まず、PCが2台あります。1つをPC_A、もう1つをPC_Bとします。
PC_A(WinXP 32bit)でPerlスクリプトとそれを何度も呼び出すシェルスクリプトを作成し、
PC_B(WinXP 64bit)で実行します。そのプログラムの概要はだいたい以下の通り。
実行環境はCygwinで、Perlのバージョンは5.8.8(64bit)です。

#!/usr/bin/perl

my $a = $ARGV[0].".ext";
my $b = $ARGV[1].".ext";
my $c = $ARGV[2].".ext";

print system("java -jar jarfile.jar $a $b $c");
以下がシェルスクリプト *1 です。
(本当はこんな規則正しいパラメータの与え方をしているわけではありません。)

./perlscript.pl 10 10 10
./perlscript.pl 10 10 20
./perlscript.pl 10 10 30
# 以下同様...

./perlscript.pl 30 30 30

で、実行させようとすると、なぜかPerlスクリプトでの最後のコマンドライン引数が
おかしなことになる
のです。表示させてみると、どうやらcarriage returnが入っている模様。
(表示が上書きされてたりするので。)

いろいろ試した結果、シェルスクリプトの行末に半角スペースを余分に入れることで対処。
でもこれまでこんな問題にぶつかったことがなかったので、かなり戸惑いましたね~。

--
(2008/02/10 追記)
コメントの内容を受けて、実行環境などを補足しました。

--
(2008/02/10 追記)
コメントより、コマンドライン引数に変な改行文字が入っていたら
次のようにしたらいいんじゃないかというアドバイスをいただきました!
ありがとうございます(^O^)/

Cygwinではデフォルトの改行文字が「LF」(Unix形式)になっているらしいですね。
Windows上で作成されたファイルでは改行文字が「CRLF」になるので、
そこが問題になっていたようです。

$line = "command line arguments\r\n"; # コマンドライン引数を代入した変数
{
    local $/ = "\r\n"; # 削除したい改行文字を設定
    chomp($line);   # 余分な改行文字を削除
}
*1 : というよりバッチファイル

トラックバック(0)

このブログ記事を参照しているブログ一覧: Perl:コマンドライン引数でつまずく

このブログ記事に対するトラックバックURL: http://trialpc.net/mt/mt-tb.cgi/1561

コメント(8)

Anonymous :

そんなときはchompを使えばおk


tetsu Author Profile Page:

chompも使ってみたんですけどこれがなかなかうまくいかず…。
実はこのPerlスクリプトやシェルスクリプトはCygwin上で
動かしてたんですけど、改行コードはCRLF(もしくはLF)
で認識されてると思うんですよねorz

で、このシェルスクリプトでは改行コードとしてCRだけが
なぜか付加されているために、chompが有効にならなかった
んじゃないかと考えてます。
僕の思い違いかもしれませんが(;´д⊂
chompはそのあたりちゃんと対応してるんでしょうか?


щ( ) ゚ д゚ (щ) :

それだけだったら,bashなら

set=$(seq 10 10 30);
for a in $set; do for b in $set; do for c in $set; 
do echo -e "java -jar javafile.jar $a.ext $b.ext $c.ext"|sh;
done;done;done;

とかで出来ないだろうか.


tetsu Author Profile Page:

実はこのサンプルは問題点をはっきりするために
ものすごく簡単にしてるのです^^;

シェルスクリプトのほうでは、サンプルのように
等間隔でパラメータを与えてるのではなくて
かなり不規則な値を取ってます。
(パラメータの組合せは60組くらい)

ついでに言うと、この実験スクリプトは実験の
2段階目で使ってるやつなのです。1段階目では
パラメータを総当りでやってるんで、だいたい
同じようなことをやってますよ(^^)v
(でも使ってる言語はPerlなんですけどねw)


щ( ) ゚ д゚ (щ) :

推測で書くけど,

一段階目の実験プログラムでパラメータ最適化(Java)



二段目の実験スクリプト用shell scriptを吐く

-WindowsなのでJAVAプログラムからの出力は[CR][LF]付与される



./perlscript.pl 10 10 30[CR][LF] が実行される



Cygwinの改行コードは[LF]なので,


my $c = $ARGV[2].".ext";
=> 30[CR].ext

ってことだろうか.

perlスクリプトはcygwinで動かしてるからchompでは[LF]しか削除しないので,うまくいかないんだな.

chompは$/の値を削除するらしいので,


{
local $/ = "\r\n";
chomp($line);
}

すればいいと思うよ.


tetsu Author Profile Page:

大体そんな感じです!
(ただ、二段目の実験スクリプト用シェルスクリプトは自分でガリガリ書いたんですけどねorz )

chompの使い方はすごく参考になりました。
まだまだPerlを使いこなすには時間がかかりそうです。
今度こんな問題にぶつかったときは、その方法で乗り切ってみたいと思います(´∇`)


http://hassylin.nowa.jp/entry/56d3166bb0

同じ問題にはまったことがあったよ


コメントする

Advertizement

このブログ記事について

このページは、tetsuが2008年2月10日 01:30に書いたブログ記事です。

ひとつ前のブログ記事は「Perlでスレッドを使う」です。

次のブログ記事は「提出日」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 5.0

カウンタ

リンク