6

open()末尾の改行を含むファイル名でperl の 2 つの引数を呼び出すと、改行が無視されます。ただし、引数が 3 つのバージョンでは改行が保持されます。

なぜ動作が異なるのですか?表向きは改行が取り除かれているのはなぜですか?

-- ファイル「nl」が存在しません。成功する

$ ls -1 nl; nlに触れてください。ls -1 nl
ls: nl: そのようなファイルまたはディレクトリはありません
nl

-- "nl\n" → ENOENT を 3 引数で開く

strace は、私が期待する動作を示しています。FWIW.

$ perl -E 'open(F, "<", "nl\n") or die $!'
-e 行 1 にそのようなファイルまたはディレクトリはありません。

$ strace -e trace=open perl -E 'open(F, "<", "nl\n") or die $!' 2>&1 | grep nl
open("nl\n", O_RDONLY|O_LARGEFILE) = -1 ENOENT (そのようなファイルまたはディレクトリはありません)

-- では、2 引数の open "nl\n" を試してください → 成功 ?

$ perl -E 'open(F, "nl\n") or die $!'

- 何?なぜそれがうまくいったのですか?strace を見てみましょう。

ああ、それは改行を無視しています:

$ strace -e trace=open perl -E 'open(F, "nl\n") or die $!' 2>&1 | grep nl
開く ("nl", O_RDONLY|O_LARGEFILE) = 3

-- 「nl」はまだそこにある唯一のファイルです

$ ls
nl

バックグラウンド:

$ パール -v

これは、i686-linux-thread-multi 用にビルドされた perl 5、バージョン 16、subversion 0 (v5.16.0) です。

4

2 に答える 2

11

perldoc perlopentut :

注意すべきもう 1 つの重要な点は、シェルと同様に、ファイル名の前後の空白は無視されることです。これらに異なることをさせたくないので、これは良いことです:

open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"

これはバグではなく、機能です。openは、リダイレクト矢印を使用してファイルを開く方法を指定するスタイルでシェルを模倣しているため、ファイル名自体の周りの余分な空白に関しても同様です。いたずらな名前のファイルにアクセスする方法については、Dweomer の Dispellingを参照してください。

open には引数が 3 つのバージョンもあり、特殊なリダイレクト文字を独自の引数に入れることができます。

この場合、開くファイル名は の実際の文字列であるため、開くモードに影響を与える可能性のある文字や、引数が 2 つのバージョンで吸収されるファイル名の先頭に空白を含めること$datafileを心配する必要はありません。$datafile. また、不要な文字列補間の削減は良いことです。

于 2012-06-28T21:59:57.873 に答える
2

それは非常に単純です: 2-argopenの構文は、パイプを許可する点までシェルの構文に近似しているためです。

于 2012-06-28T22:05:19.300 に答える