Ls - sıfır veya -0 seçeneğinin olmaması için bir neden var mı?


37

Bu soru, ls' -1seçeneği ve insanların soru sorma eğilimi ve çıktılarının işlenmesini de içeren cevapları ile ilgili sorular tarafından yönlendirildi ls.

Çıktının bu yeniden kullanımı lsanlaşılabilir görünmektedir, örneğin: bir dosya listesini nasıl sıralayacağınızı biliyorsanız ls, çıktıyı başka bir şey için girdi olarak kullanmak isteyebilirsiniz.

Bu Soru ve Cevaplar, güzel davranan dosya adlarından oluşan (boşluklar ve yeni satırlar gibi özel karakterler içermeyen) üretilen dosya adı listesine bir referans içermiyorsa, genellikle orada iken komut dizisinin çalışmaması tehlikesini belirten biri tarafından yorumlanır. Yeni satırlı, boşluklu vb. dosyalardır.

find, sortVe diğer yardımcı programları ör için "zor" dosya adları iletişim sorunu çözmek xargsdosya adı geçerli bir karakter değil boş karakter / bayt ile dosya adlarını ayırmak için bir seçeneği kullanarak (ek olarak yalnızca tek /?) Üzerinde Unix / Linux dosya sistemleri.

İçin man sayfasına lsve çıkışının ls --help(listelenen daha fazla seçeneğe sahip olduğu) baktım ve ls(from coreutils) 'ın NUL ayrılmış çıkış belirtme seçeneği olduğunu bulamadım . Bu bir var -1olarak yorumlanabilir seçeneği "yeni satır ile ayrılmış çıktı dosya adları" )

S : "NUL ile ayrılmış dosya isimlerini çıkaracak" lsbir seçeneğin --zeroveya -0seçeneğin olmamasının teknik veya felsefi bir nedeni var mı?

Yalnızca dosya adlarını çıkaran bir şey yaparsanız (ve eg kullanmıyorsanız -l) anlamlı olabilecek:

ls -rt -0 | xargs -r0 

Bunun neden işe yaramayacağına dair bir şey eksik olabilir veya bu örnek için göz ardı ettiğim ve çok daha karmaşık ve / veya belirsiz olmayan bir alternatif var .


Zeyilname:

Yapma ls -lrt -0muhtemelen çok mantıklı değil, aynı şekilde find . -ls -print0bir sağlamaz için bir neden değildir, bu yüzden değil -0/ -z/ --zeroseçeneği.


Yapılacak açık bir şey GNU coreutil'lerine böyle bir seçenek hakkındaki düşüncelerinin ne olduğunu yazmak ve sormaktır.
Faheem Mitha

1
ls -rtzkesinlikle faydalı olurdu. Alternatifin aksine: superuser.com/a/294164/21402
Tobu

Yanıtlar:


37

GÜNCELLEME (2014-02-02)

Bizim çok kendi sayesinde Anthon en @ içinde kararlılıkla bu özelliğin kadar eksikliğini takip , biz bu özellik daha önce de açıklandığı Ne yinelemektedir ki, eksik neden olarak biraz daha resmi neden var:

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

Yama için çok teşekkürler. Bunu yapacak olsaydık, kullanacağımız arayüz bu olurdu. Bununla birlikte, bu gerçekten bir insan tarafından doğrudan tüketim için bir araçtır ve bu durumda daha fazla işlem daha az faydalıdır. Daha fazla işleme için, bul (1) daha uygundur. Bu, yukarıdaki bağlantıdaki ilk cevapta iyi tanımlanmıştır.

Yani buna eklemeye karşı 70:30 olurdum.

Orijinal cevabım


Bu benim kişisel görüşümün bir kısmı, ancak bu değişikliğin dışında bırakılmasında tasarım kararı olduğuna inanıyorum ls. findKomutun bu anahtara sahip olduğunu fark ederseniz :

-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.

Bu kapatmayı bırakarak tasarımcılar lsçıktınızı, insan tüketiminden başka hiçbir şey için kullanmamanız gerektiğini ima ediyorlardı . Diğer araçlar tarafından akış aşağı işleme için, findbunun yerine kullanmanız gerekir .

Kullanma yolları bulmak

Alternatif yöntemleri arıyorsanız, bunları burada bulabilirsiniz: Başlığı doğru şekilde yapma: Hızlı bir özet . Bu bağlantıdan bunlar muhtemelen daha yaygın olan 3 modeldir:

  1. Basit Bul -exec; Eğer COMMAND büyükse, 1 işlem / dosya oluşturur:
    find . -exec COMMAND... {} \;
  2. COMMAND için birden fazla dosya tamamsa basit + ile -ecec bulun
    find . -exec COMMAND... {} \+
  3. \ 0 ayırıcıyla find ve xargs öğelerini kullanın

    (standart olmayan yaygın uzantılar -print0 ve -0. GNU, * BSD'ler, busybox'ta çalışır)

    find . -print0 | xargs -0 COMMAND

Daha fazla kanıt?

Bu blog yazısını Joey Hess'in blogundan buldum: " ls: eksik seçenekler ". Bu yayındaki ilginç yorumlardan biri:

Şu andaki tek belirgin eksiklik, çıktı dosya adlarının diğer programlar tarafından kabul edilmesi için NULL olarak sonlandırılması gereken bir -z seçeneğidir. Bunun kolay yazılabileceğini düşünüyorum, ancak son derece meşgul IRL (bir sürü mobilya taşıyordum) ve anlamadım. Yazmak isteyen var mı?

Ayrıca Joey blog yazısı "kelimesinin geçtiği ek anahtarların birinden günlükleri işlemek bunu buldum arama yeni çıkış biçimi -j o blog yazısı hiç bir ekleme kavramı dalga geçer oldu gibi görünüyor, bu yüzden" -zanahtarı ls.

Diğer seçeneklere gelince, birden fazla kişi -e neredeyse işe yaradığını kabul etse de, hiçbirimiz kullanmak için bir neden bulamayız. Hata raporum, ls -eR'nin çok arabası olduğunu söylemeyi ihmal etti. -j açıkça şaka yapıyor.

Referanslar


Teşekkür ederim. Ben uyarıların farkındayım. Çıktı işleme ile ilgili hiçbir soru, işaret etmeden tamamlanmadı ;-)
Timo

@Timo - Yaptığını biliyorum, bu Q’nun gelecekteki okuyucuları için daha fazlasını yapıyordum. Sizi sitede görüyorum, bunlar şu ana kadar aramalarınızda ortaya çıkacaktı: 8-)
slm

Bunu farkettim ve iyi yaptın. -0İnsanları yoldan saptırmamak için soruma neden (en azından uygulanana kadar ) neden atılmamalıydı .
Timo

Elbette, dosya adındaki '\ n' gibi gerçekten egzotik bir şey olmadığını varsayarsak, ls -1 | tr '\012' '\000'NULL karakterlerle ayrılmış dosyaları listeler.
samiam

2
Bu makale, dosya isimlendirme sorunlarının derinliklerine giriyor: dwheeler.com/essays/fixing-unix-linux-filenames.html
slm

20

@ Slm'in cevapları kökenleri ve olası nedenleri gider gibi ben burada tekrar etmeyeceğim. Böyle bir seçenektir değil coreutils üzerinde özellik listesine reddedilen , ancak aşağıda yama olduğu şimdi Pádraig Brady tarafından reddedilen posta listesine coreutils göndermeden sonra. Cevaptan anlaşılacağı gibi bu felsefi bir sebep ( lsçıktı insan tüketimi içindir).

Böyle bir seçeneğin kendiniz için uygun olup olmadığını denemek istiyorsanız, şunları yapın:

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

sonra b938b6e289ef78815935ffa705673a6a8b2ee98e dd 2014-01-29 numaralı taahhütleri karşı aşağıdaki yamayı uygulayın:

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

Başka bir markadan sonra:

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

Bu yüzden yama çalışıyor ve neden olmasın diye bir neden göremiyorum, ancak bu seçeneği dışlamak için hiçbir teknik neden olmadığı kanıtı değil. ls -R0yok ne kadar mantıklı, ama olmayabilir ls -Rmhangi lskutunun dışında yapabilirsiniz.


Sahip olmak -zve --zerosıralama ile aynı hizada (aynı zamanda coreutils içinde.
Anthon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.