Komut seçeneklerinde bir dosya yerine bir kanaldan okunan verileri kullanma


18

İnsan tanımı başına, bu komut girdiyi bir dosyadan alır.

$ command -r FILENAME

FILENAMEBunun, oluşturulduğu şekliyle bir dosya adları listesi içeren bir dosya olduğunu varsayalım ls > FILENAME.

Bunun yerine, komutu lsdoğrudan sonucuyla nasıl besleyebilirim ? Kafamda böyle bir şey mümkün olmalı:

$ ls | command -r

Ama öyle değil, çıktısı lsbir argüman olarak bağlanmaz. Çıktı:

Usage: command -r FILENAME
error: -r option requires an argument

İstenen etkiyi nasıl elde edebilirim?


İlgili bir soruyla ilgili daha fazla yanıt: Bir dizeyi dosya bekleyen bir komuta nasıl iletirim?
ilkkachu

Yanıtlar:


31

Bu komuta bağlıdır. Bir dosyadan okunan bazı komutlar, dosyanın boyutu önceden bilinen ve herhangi bir konumdan okunabilen ve geri alınabilen normal bir dosya olmasını bekler. Dosyanın içeriği bir dosya adları listesiyse bu olası değildir: o zaman komut muhtemelen başından sonuna kadar sıralı olarak okuyacağı bir boru ile içerik olacaktır. Veriyi kanal yoluyla dosya adı bekleyen bir komuta beslemenin birkaç yolu vardır.

  • Birçok komut -özel bir ad olarak kabul edilir, yani bir dosyayı açmak yerine standart girdiden okumak anlamına gelir . Bu bir sözleşmedir, bir yükümlülük değildir.

    ls | command -r -
  • Birçok unix varyantı /dev, standart tanımlayıcıları belirten özel dosyalar sağlar . Varsa /dev/stdin, onu açmak ve okumak, standart girdiden okumakla eşdeğerdir; aynı şekilde /dev/fd/0varsa.

    ls | command -r /dev/stdin
    ls | command -r /dev/fd/0
  • Kabuğunuz ksh, bash veya zsh ise, kabuğun bazı dosya tanımlayıcılarını ayırma işi ile ilgilenmesini sağlayabilirsiniz. Bu yöntemin ana avantajı, standart girdiye bağlı olmamasıdır, bu nedenle başka bir şey için standart girişi kullanabilir ve bir kereden fazla kullanabilirsiniz.

    command -r <(ls)
  • Komut adın belirli bir forma (genellikle belirli bir uzantıya) sahip olmasını beklerse, bunu sembolik bir bağlantıyla aldatmayı deneyebilirsiniz.

    ln -s /dev/fd/0 list.foo
    ls | command -r list.foo

    Veya adlandırılmış bir boru kullanabilirsiniz.

    mkfifo list.foo
    ls >list.foo &
    command -r list.foo

O Not ile dosyaların bir listesini oluşturmaya lsproblemlidir çünkü lsonlar basılamaz karakterler içerdiğinde mangle dosya adları eğilimindedir. printf '%s\n' *daha güvenilirdir - her baytı tam anlamıyla dosya adlarında yazdırır. Yeni satırlar içeren dosya adları yine de soruna neden olur, ancak komut yeni satırlarla ayrılmış dosya adlarının bir listesini beklerse bu kaçınılmazdır.


Tüm olasılıkları listelemek için +1. IMO süreç ikamesi bu durum için doğru cevaptır.
glenn jackman

7

Olmalı:

ls | xargs -n 1 command -r

Düzenle: boşluklu adlar için:

ls | xargs -d '\n' -n 1 command -r

commandKomut satırında bir kerede ihtiyaç duyacağı tüm dosya adlarına sahip olduğuna inanıyorsa, bu sorunlu olabilir . Bazı xargs sürümleri aynı anda commandbirkaç dosya adı (10, bana öyle geliyor) verecektir . Görünüşe göre GNU xargs her şeyi aynı anda veriyor.
Bruce Ediger

2

Aslında, içinde yeni satır bulunanlar da dahil olmak üzere tüm dosya adlarını işleyebileceğini bildiğim tek güvenilir çözüm:

find . -maxdepth 1 -print0 | xargs -n 1 -0 command -r

Bu durumda dosya adında izin verilmeyen tek karakter, dosya adlarında zaten izin verilmeyen boş karakterdir.


1

Birçok komut -"standart girdi kullan" anlamına gelen "dosya adı" olarak kabul edilir, ancak bu kural evrensel olmaktan uzaktır. Kılavuz sayfasını okuyun.


1

Bu sizin amacınıza uygun olmalıdır: ls | command -r /dev/stdin

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.