lsに--zeroまたは-0オプションがない理由はありますか


37

この質問はls' -1オプションについての質問によって促されましたls

この出力の再利用はls理解できるように思えます。たとえば、ファイルのリストを並べ替える方法を知っlsている場合は、その出力を他の何かの入力として使用できます。

これらのQ&Aに、適切に動作するファイル名(スペースや改行などの特殊文字は含まれない)で構成されるファイル名リストへの参照が含まれていない場合、コマンドシーケンスが動作しない場合の危険性を指摘する誰かによってコメントされることがよくあります改行、スペースなどを含むファイルです。

findsortおよび他のユーティリティは、「困難な」ファイル名を通信する問題を解決します。たとえばxargs、ファイル名の有効な文字ではないNUL文字/バイトでファイル名を区切るオプションを使用します/。 Unix / Linuxファイルシステム。

私は(より多くのオプションがリストされています)のmanページlsと出力をls --help探しましたが、ls(from coreutils)にはNULで区切られた出力を指定するオプションがありませんでした。それは持っている-1と解釈できるオプション「改行で区切って出力ファイル名を」

Q:「NULで区切られたファイル名を出力する」またはオプションlsがない理由は技術的または哲学的な理由ですか?--zero-0

意味のあるファイル名のみを出力する(たとえば、使用しない-l)ことを行う場合:

ls -rt -0 | xargs -r0 

なぜこれが動作しない、私は何かが欠けていることができ、あるいは私が見落としていることを、この例の代替があり、それははるかに複雑かつ/または不明瞭ではありませんが


補遺:

行うことはls -lrt -0おそらくあまり意味がありfind . -ls -print0ませんが、そうしないのと同じ方法で、-0/ -z/ --zeroオプションを提供しない理由にはなりません。


すべきことは、GNU coreutilsのメンテナーにそのようなオプションについての考えを書いて尋ねることです。
ファヒームミタ14

1
ls -rtz間違いなく便利でしょう。代替案と対照的に:superuser.com/a/294164/21402
東武

回答:


37

更新(2014-02-02)

この機能の欠如をフォローするという独自の@Anthonの決意のおかげで、この機能が欠如している理由についてもう少し正式な理由があります。

Re: [PATCH] ls: adding --zero/-z option, including tests

From:      Pádraig Brady
Subject:   Re: [PATCH] ls: adding --zero/-z option, including tests
Date:      Mon, 03 Feb 2014 15:27:31 +0000

パッチをありがとう。これを行う場合、これは使用するインターフェイスです。ただし、lsは実際には人間が直接消費するためのツールであり、その場合、それ以上の処理はあまり役に立ちません。さらに処理するには、find(1)の方が適しています。これについては、上記のリンクの最初の回答で詳しく説明されています。

だから、これを追加することに対して70:30です。

私の元の答え


これは私の個人的な意見の少しですが、私はそれがそのスイッチを去ることにおけるデザイン決定であると信じlsます。findコマンドにこのスイッチがあることに気づいた場合:

-print0
      True; print the full file name on the standard output, followed by a 
      null character (instead of the newline character that -print uses).  
      This allows file  names  that  contain  newlines or other types of white 
      space to be correctly interpreted by programs that process the find 
      output.  This option corresponds to the -0 option of xargs.

そのスイッチを除外することにより、設計者はls、人間が消費する以外の目的で出力を使用すべきではないことを暗示していました。他のツールによるダウンストリーム処理の場合は、find代わりに使用する必要があります。

findの使用方法

代替方法を探している場合は、ここでそれらを見つけることができます:タイトル:正しく実行する:簡単な要約。そのリンクから、これらはおそらく3つのより一般的なパターンです。

  1. 単純な検索-exec; COMMANDが大きく、プロセス/ファイルが1つ作成されると扱いにくくなります。
    find . -exec COMMAND... {} \;
  2. +を使用した単純な検索-exec。複数のファイルがCOMMANDで問題ない場合は高速です。
    find . -exec COMMAND... {} \+
  3. findおよびxargsを\ 0区切り文字とともに使用します

    (非標準の共通拡張機能-print0および-0。GNU、* BSD、busyboxで動作します)

    find . -print0 | xargs -0 COMMAND

さらなる証拠?

Joey Hessのブログ「ls:the missing options」というタイトルのこのブログ投稿を見つけました。この投稿の興味深いコメントの1つ:

現在の唯一の明らかな不足は、出力ファイル名を他のプログラムが使用できるようにNULLで終了させる-zオプションです。これを書くのは簡単だと思いますが、私はIRL(たくさんの家具を動かす)に忙しくて、それに着きませんでした。書く人はいますか?

さらに検索すると、Joeyのブログ投稿で言及されている追加のスイッチの1つである「新しい出力形式-j」のコミットログでこれが見つかりまし-zls

他のオプションについては、複数の人が-eがほぼ有用であることに同意しますが、それを使用する理由を見つけることはできません。私のバグレポートでは、ls -eRが非常にバグだと言及することを怠っていました。-jは明らかに冗談です。

参照資料


ありがとうございました。警告を認識しています。ls出力処理についての質問は、それを指摘することなく完了します;-)
Timo 14

@Timo-知っています、このQの将来の読者のためにもっとや​​っていました。サイトであなたに会いました。これらは今までの検索で出てきたものです8
slm

私はそれを実感しました、そしてあなたがしたことは良いことです。-0人々を惑わさないために、(少なくとも実装されるまでは)なぜそうでないのかについての言及を私の質問に含めるべきでした。
ティモ14

もちろん、ファイル名に '\ n'のような本当にエキゾチックなものがないと仮定ls -1 | tr '\012' '\000'すると、NULL文字で区切られたファイルがリストされます。
samiam

2
この記事では、ファイル名の問題の深さについて説明します。dwheeler.com
slm

20

@slmの答えは起源と考えられる理由にあるので、ここでは繰り返しません。そのようなオプションはcoreutils 拒否機能リストにはありませんが、coreutilsメーリングリストに送信した後以下のパッチPádraigBradyによって拒否されました。答えから、これが哲学的理由であることは明らかです(出力は人間が消費するものです)。 ls

そのようなオプションが自分にとって妥当かどうか試してみたい場合は、次のようにします。

git clone git://git.sv.gnu.org/coreutils
cd coreutils
./bootstrap
./configure
make

その後、コミットb938b6e289ef78815935ffa705673a6a8b2ee98e dd 2014-01-29に対して次のパッチを適用します。

From 6413d5e2a488ecadb8b988c802fe0a5e5cb7d8f4 Mon Sep 17 00:00:00 2001
From: Anthon van der Neut <address@hidden>
Date: Mon, 3 Feb 2014 15:33:50 +0100
Subject: [PATCH] ls: adding --zero/-z option, including tests

* src/ls.c has the necessary changes to allow -z/--zero option to be
  specified, resulting in a NUL seperated list of files. This
  allows the output of e.g. "ls -rtz" to be piped into other programs

* tests/ls/no-args.sh was extended to test the -z option

* test/ls/rt-zero.sh was added to test both the long and short option
  together with "-t"

This patch was inspired by numerous questions on unix.stackexchange.com
where the output of ls was piped into some other program, invariably
resulting in someone pointing out that is an unsafe practise because of
possible newlines and other characters in the filenames.
---
 src/ls.c            |   31 +++++++++++++++++++++++++------
 tests/ls/no-arg.sh  |    7 ++++++-
 tests/ls/rt-zero.sh |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 7 deletions(-)
 create mode 100755 tests/ls/rt-zero.sh

diff --git a/src/ls.c b/src/ls.c
index 5d87dd3..962e6bb 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -381,6 +381,7 @@ static int file_size_width;
    many_per_line for just names, many per line, sorted vertically.
    horizontal for just names, many per line, sorted horizontally.
    with_commas for just names, many per line, separated by commas.
+   with_zero for just names, one per line, separated by NUL.

-l (and other options that imply -l), -1, -C, -x and -m control

    this parameter.  */
@@ -391,7 +392,8 @@ enum format
     one_per_line,              /* -1 */
     many_per_line,             /* -C */
     horizontal,                        /* -x */
-    with_commas                        /* -m */
+    with_commas,               /* -m */
+    with_zero,                 /* -z */
   };

static enum format format;

@@ -842,6 +844,7 @@ static struct option const long_options[] =
   {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
   {"context", no_argument, 0, 'Z'},
   {"author", no_argument, NULL, AUTHOR_OPTION},
+  {"zero", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -850,12 +853,12 @@ static struct option const long_options[] =
 static char const *const format_args[] =
 {
   "verbose", "long", "commas", "horizontal", "across",
-  "vertical", "single-column", NULL
+  "vertical", "single-column", "zero", NULL
 };
 static enum format const format_types[] =
 {
   long_format, long_format, with_commas, horizontal, horizontal,
-  many_per_line, one_per_line
+  many_per_line, one_per_line, with_zero
 };
 ARGMATCH_VERIFY (format_args, format_types);

@@ -1645,7 +1648,7 @@ decode_switches (int argc, char **argv)

     {
       int oi = -1;
       int c = getopt_long (argc, argv,
-                           "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
+                           "abcdfghiklmnopqrstuvw:xzABCDFGHI:LNQRST:UXZ1",
                            long_options, &oi);
       if (c == -1)
         break;
@@ -1852,6 +1855,10 @@ decode_switches (int argc, char **argv)
             format = one_per_line;
           break;

+ case 'z':

+          format = with_zero;
+          break;
+
         case AUTHOR_OPTION:
           print_author = true;
           break;
@@ -2607,7 +2614,8 @@ print_dir (char const *name, char const *realname, bool 
command_line_arg)
                  ls uses constant memory while processing the entries of
                  this directory.  Useful when there are many (millions)
                  of entries in a directory.  */
-              if (format == one_per_line && sort_type == sort_none
+              if ((format == one_per_line || format == with_zero)
+                      && sort_type == sort_none
                       && !print_block_size && !recursive)
                 {
                   /* We must call sort_files in spite of
@@ -3598,6 +3606,14 @@ print_current_files (void)
         }
       break;

+ case with_zero:

+      for (i = 0; i < cwd_n_used; i++)
+        {
+          print_file_name_and_frills (sorted_file[i], 0);
+          putchar ('\0');
+        }
+      break;
+
     case many_per_line:
       print_many_per_line ();
       break;
@@ -4490,6 +4506,7 @@ print_many_per_line (void)
           indent (pos + name_length, pos + max_name_length);
           pos += max_name_length;
         }
+      putchar ('X'); // AvdN
       putchar ('\n');
     }
 }
@@ -4780,7 +4797,8 @@ Sort entries alphabetically if none of -cftuvSUX nor 
--sort is specified.\n\
   -F, --classify             append indicator (one of */=>@|) to entries\n\
       --file-type            likewise, except do not append '*'\n\
       --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
-                               single-column -1, verbose -l, vertical -C\n\
+                               single-column -1, verbose -l, vertical -C,\n\
+                               zeros -z\n\
       --full-time            like -l --time-style=full-iso\n\
 "), stdout);
       fputs (_("\
@@ -4888,6 +4906,7 @@ Sort entries alphabetically if none of -cftuvSUX nor 
--sort is specified.\n\
   -X                         sort alphabetically by entry extension\n\
   -Z, --context              print any security context of each file\n\
   -1                         list one file per line\n\
+  -z, --zero                 list files separated with NUL\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
diff --git a/tests/ls/no-arg.sh b/tests/ls/no-arg.sh
index e356a29..da28b96 100755
--- a/tests/ls/no-arg.sh
+++ b/tests/ls/no-arg.sh
@@ -30,11 +30,16 @@ out
 symlink
 EOF

-

 ls -1 > out || fail=1

compare exp out || fail=1 +/bin/echo -en "dir\00exp\00out\00symlink\00" > exp || framework_failure_

+
+ls --zero > out || fail=1
+
+compare exp out || fail=1
+
 cat > exp <<\EOF
 .:
 dir
diff --git a/tests/ls/rt-zero.sh b/tests/ls/rt-zero.sh
new file mode 100755
index 0000000..cdbd311
--- /dev/null
+++ b/tests/ls/rt-zero.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Make sure name is used as secondary key when sorting on mtime or ctime.
+
+# Copyright (C) 1998-2014 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ ls touch
+
+date=1998-01-15
+
+touch -d "$date" c || framework_failure_
+touch -d "$date" a || framework_failure_
+touch -d "$date" b || framework_failure_
+
+
+ls -zt a b c > out || fail=1
+/bin/echo -en "a\00b\00c\00" > exp
+compare exp out || fail=1
+
+rm -rf out exp
+ls -rt --zero a b c > out || fail=1
+/bin/echo -en "c\00b\00a\00" > exp
+compare exp out || fail=1
+
+Exit $fail
--
1.7.9.5

別のメイクの後、次の方法でテストできます。

  src/ls -rtz | xargs -0 -n1 src/ls -ld

そのため、パッチは機能しますが、機能しない理由はわかりませんが、オプションを除外する技術的な理由がないという証拠ではありません。ls -R0あまり意味がありませんが、どちらもないではないかもしれないls -Rmそのls箱から出して行うことができます。


持つ-z--zerocoreutilsの中でも、(ソートに沿って、より多くのです。
Anthonの
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.