2017-02-16 5 views
1

私はPerlで小さなスクリプトを作成しました。これは本当に新しいものです。私は、与えられた引数を見て、与えられた引数にディレクトリツリーを作成するスクリプトを用意しなければなりません。スクリプトのこの部分は機能します。 2番目の部分(ネストされたif文)は、引数を与えないと表示されず、選択したディレクトリを入力するように求められます。私は入れ子のif文が$ファイル入力のためにうんざりしていると信じていますが、私は何が間違っているのか完全にはわかりません。これはおそらく単純なものですが、解決策を見つけることができませんでした。ヘルプとヒントをお寄せいただきありがとうございます。 STDINを介して入力されているものも改行を持っているので、PerlスクリプトIF文を実行している小さな問題があります。

#! /usr/bin/perl 

if ($#ARGV == -1) 
{ 
    print "Please enter default directory:"; 
    my $file=<STDIN>; 

    if (-d $file) 
    { 
     chdir $file; 
     system("mkdir Data"); 
     system("mkdir Data/Image"); 
     system("mkdir Data/Cache"); 
     print "Structure Created"; 
    } 
    else 
    { 
     print "Directory does not exsist"; 
    } 
} 
else 
{ 
    chdir $ARGV[0]; 
    system("mkdir Data"); 
    system("mkdir Data/Image"); 
    system("mkdir Data/Cache"); 
    print ("Structure Created"); 
} 
print ("\n"); 
+2

$dir名を含め、あなたがそれを読んだ後、 ''ムシャムシャ食べる($ファイル)が必要です。STDIN'は、改行が付属しており、 '-d $ file'」doesnの'経由で入力されると何'filename \ n'を見つけてください(本当に' filename'です)。また、 '@ ARGV'の最後の要素のインデックス(' $#ARGV'は何ですか?)について '-1'をテストするのはなぜですか? '@ ARGV'配列が空であるかどうかをテストしているなら' if(not @ARGV) 'と書くことができます – zdim

+0

' $ file'変数を使ってディレクトリ名を保持すると、混乱するかもしれません。引数の先頭からスクリプトの先頭を取り出します。 'if(!@ARGV){die" argsが指定されていません... \ n "; }; $ my dir = $ ARGV [0]; '。 ''は、プログラムが実行されている間に、コマンドラインで送信したものをすべて取ります。これはコマンドラインのargs( 'ARGV')とは異なります。 (@zdimは、改行を取り除く方法をコメントで示しました)。いくつかの最適化がありますが、完全な答えを定式化するのに十分な情報はありません。 – stevieb

+0

@steviebコマンドラインで何も提出されていなければ、 'STDIN'入力を提供することを意味すると思います。そうであれば、 '@ ARGV'が空のときに' die'することはできません。私はそれが少し不明であることに同意する。 – zdim

答えて

3

テスト-d $fileは、ディレクトリ名を指定する文字列の後に、失敗しています。必要がありますchomp($file);


ただし、いくつかの点をご紹介します。

最も重要なことは、両方のブランチに繰り返しコードがあることです。あなたは本当にそれをしたくありません。それは後でトラブルを引き起こす可能性があります。代わりに、ディレクトリ名を決定し、それを作成します。

第2に、ディレクトリを作成するためにシステムに出る理由はありません。 Perlでそれを行うほうがはるかに優れており、これには良いモジュールがあります。

use strict; 
use warnings; 
use File::Path qw(make_path); 

my $dir;  
if (not @ARGV) { 
    print "Please enter default directory: "; 
    $dir = <STDIN>; 
    chomp $dir; 
} 
else { 
    $dir = $ARGV[0]; 
} 
die "No directory $dir" if not -d $dir; 

my $orig_cwd = chdir $dir or die "Can't chdir to $dir: $!"; 

my @dirs = map { "Data/$_" } qw(Image Cache); 

my @dirs_made = make_path(@dirs, { verbose => 1 }); 

print "Created directories:\n"; 
print "$_\n" for @dirs_made; 

私はData/...mapので、繰り返しを避けるために、文字列を使用してディレクトリのリストを作成し、後で柔軟性のために。もちろん名前を入力することはできますが、それは愚かな間違いを招く傾向があります。

私はFile::Pathを使用してディレクトリを作成しました。 mkdir -pのような全体のパスを構築し、エラー処理を含めて{ }に渡すことができるその他の便利なオプションがいくつかあります。他のモジュールもあります。たとえば、とmkpath(その他多くのもの)があります。

chdirを使用すると、現在の作業ディレクトリを記録し、それが戻ってきて、エラーをチェックしたいと思うでしょう。しかし、それ以外の理由がない場合は、chdirにする必要はありません。ただ、map

# No chdir needed here 
my @dirs = map { "$dir/Data/$_" } qw(Image Cache); 
関連する問題