簡単な答え:system
コマンドからの出力は返されません。終了値を返します。の出力はcut
リダイレクトされないため、現在の STDOUT (端末など) に出力されます。open
またはqx//
引用符 (別名バッククォート) を使用して出力をキャプチャします。
@names = `cat /etc/passwd | cut -f 1 -d :`;
あなたはまだ Perl を学んでいるので、私がその問題を解決する方法を詳しく説明した記事を以下に示します。
まず、常にuse strict; use warnings;
スクリプトの先頭に。これは、多くの問題を防止および検出するのに役立ち、非常に役立ちます。
次に、すべてを Perl 内で実行できる場合にシェルを開始するのは非効率的です (ソリューションは 6 つの不要なプロセス ( sh
、cat
、の 2 つのセットcut
) を開始します)。実はcat
シェル版でもだめなのです。シェルリダイレクト演算子を使用するだけです: cut ... </etc/passwd
.
Perl でファイルを開くには、次のようにします。
use autodie; # automatic error handling
open my $passwd, "<", "/etc/passwd";
は"<"
モードです (ここでは: 読み取り)。$passwd
変数は、次のような行を読み取ることができるファイル ハンドルを保持するようになりまし<$passwd>
た。行にはまだ改行が含まれているためchomp
、変数を追加します (行末を削除します)。
while (<$passwd>) { # <> operator reads into $_ by default
chomp; # defaults to $_
...
}
ビルトインは、split
区切り記号、文字列 (デフォルトは$_
変数)、およびオプションの制限に一致する正規表現を取ります。フィールドのリストを返します。文字列を:
セパレータで分割するには、次のようにします
my @fields = split /:/;
左辺は配列である必要はありません。変数のリストを指定することもできます。これは右側のリストと一致し、各変数に 1 つの要素を割り当てます。フィールドをスキップしたい場合は、次のように名前を付けますundef
。
my ($user, undef, $id) = split /:/;
ここで、ユーザーを印刷したいだけです。print
そのために次のコマンドを使用できます。
print "$user\n";
perl5 v10 以降、このsay
機能を使用できます。これは print とまったく同じように動作しますが、出力に改行を自動追加します:
say $user;
そしてほら、最終的なスクリプトがあります:
#!/usr/bin/perl
use strict; use warnings; use autodie; use feature 'say';
open my $passwd, "<", "/etc/passwd";
while (<$passwd>) {
chomp;
my ($user, undef, $id) = split /:/;
say $user;
}
アンティークパールの編集
このautodie
モジュールは、v10.1 でコア モジュールとして配布されました。また、feature 'say'
v10 より前では使用できません。
したがって、print
代わりに使用say
して、手動のエラー処理を行う必要があります。
#!/usr/bin/perl
use strict; use warnings;
open my $passwd, "<", "/etc/passwd" or die "Can't open /etc/passwd: $!";
while (<$passwd>) {
chomp;
my ($user, undef, $id) = split /:/;
print "$user\n";
}
open
は、失敗すると false の値を返します。その場合、$!
変数はエラーの理由を保持します。