Karakterleri bir dosyadan gelmiş gibi bir komuta nasıl gönderebilirim?


22

Karakterleri bir dosyadan gelmiş gibi bir komuta nasıl gönderebilirim?

Mesela denedim:

wc < "apple pear orange"
-bash: apple pear orange: No such file or directory

Yanıtlar:



18

Diğer iki yaklaşım (ekstra çaba göstermeden çoklu hat girişine izin veren):

  1. Bir "burada belge" kullanın:

    $ wc << EOF
    elmalı armut
    EOF
      1 3 18
    $

    EOFDize bir ayırıcı. Herhangi bir dize kullanabilirsiniz; EOFsadece geleneksel bir seçimdir.

  2. Tty'yi girdi olarak kullanın:

    $ wc
    elmalı armut
    Ctrl+D
      1 3 18
    $

    Bu programın çalışmaya başlamasının dezavantajına sahiptir ve adını girdiğiniz anda girişi okumaya başlar. Bu endişe verici olabilir; Örneğin:

    $ grep v
    Çabuk kahverengi tilki              (daktiloda) 
    atlar                       (daktiloda) 
    atlar                       (bu grep'ten çıktı!) 
    Tembel köpeği.                   (yazılan)
    Ctrl + D
                                    (Burada çıktı yok) 
    $

Kayıt için: <<<Form aynı zamanda fazladan çaba gerektirmeden çoklu hat girişine izin verir, çünkü "açık dizge yeni satırlar içerebilir. Elbette << EOF, çok satırlı girişiniz varsa , formu (orijinal burada-doc sözdizimi) okumak kolaydır.
alexis

Man sayfası burada dize sözdiziminin <<< wordelbette, kabuk bağlamında, wordboşluklar ve yeni satırlar içeren bir alıntı dize olabileceğini söylüyor. D'oh! Bu söylenmeden gittiği çok açık (ve aslında, man sayfasında hiç görmüyorum). :-( Bana gösterdiğin için teşekkür ederim!
G-Man 'Monica'yı Yeniden Girin'

Gerçekten basit ya da açık demezdim. A word, sayfadaki "Kabuk tarafından tek bir birim olarak kabul edilen bir karakter dizisi" (aka "token") olarak tanımlanır ve alıntılanan dizelerin ilgili anlamda (tek bir birim olarak) ele alındığını bilmeniz gerekir (sonra Ters eğik çizgi vb değişken genişleme işleme" ama aslında bütün kabuk işleme modeli çok iyi düşünülmüş bir çift alıntı kabukta amacı (tek tırnak işareti de genişleme korumak.) ve bir şey ama basit olduğunu..
alexis

@alexis: Ben böyle yukarı doğru gittiğimde ve bir ifade eklediğimde , kişi ironik olma ihtimalini göz önünde bulundurmalı.
G-Man,

10

Burada birkaç geçerli çözüm olmasına rağmen, bazen yararlı olabilecek başka bir sözdizimi de komut çalıştırmaktır <(). Bu, komut satırında 1'den fazla dosya tanıtıcı nesnesi oluşturmanıza izin verir.

Uzun metin dizelerini karşılaştırmak gibi bir şey yaparken ya da dosyada olmayan bir içeriği dağıtmak istediğinizde bu yararlı olabilir.

Örneğin, ana bilgisayar dosyasını localhost'a kopyalamak zorunda kalmadan ana bilgisayar dosyalarını iki düğümde karşılaştırarak:

diff -Naur <(cat /etc/hosts) <(ssh -q otherhost 'cat /etc/hosts')

<STDIN bir dosya yönlendirmeleri ve ()parantez arasındaki komutunu çalıştırmak için bir altkabuk oluşturun. Çalıştırılan komutun STDIN'ine iletilen alt kabuktan STDOUT'dur.

Komutta birden fazla giriş "dosyası" oluşturmak, burada birden çok dokümanı kullanmaya çalışmak veya son komutun bir boru hattına birden çok komut eko yapmaktan daha kolay bir yoldur.


<fileorpathnamestdin yönlendirir, ancak <(subcmd)yapmaz; Program tarafından / eğer açıldığında stdout'u subcmd'den okuyabilecek bir isim kullanılır. < <(subcmd)(boşluk gerekli) stdin'i bu dosyadan yönlendirir, neredeyse subcmd |. Sizin diffokuyabilir birini bir argüman belirterek Stdin'den girişlerinden -ikisini birden değil.
dave_thompson_085

Yapılmadığını iddia ettiğiniz parçalardan farklı olarak, desteklenmeyen süreç değişimi (ancak açıklandığı gibi değil).
phk

1
Farklılığım, Ubuntu 16.04 ve test etmem gereken Solaris 11.2 sistemlerinde çok iyi çalışıyor. Tüm işletim sistemlerinde tüm mermilerde çalışmayabilir. Aslında, bir dosyayı okuyormuş gibi alt işlemden gelen çıktıyı okumak için kullanılabilecek dosya tanımlayıcıları yaratıyor. Diff iki dosya argümanı aldığından, her iki alt işlemin çıktısını oluşturulan dosya tanımlayıcıları aracılığıyla okuyabilir ve karşılaştırabilir.
Tim Kennedy,

Sen arasında cevabınıza farkı eklemek isteyebilirler cmd <(cmd2 ...)ve cmd < <(cmd2 ...). Birincisi türetilmiş verilerin (cmd2'nin çıktısı) bir dosya adı yerine kullanılmasına izin verir. Sonuncusu eşdeğerdir cmd2 ... | cmd. Komutlar açıkça stdin girdisini kabul etmek için yazılmalıdır ve çoğu değildir. Bu özellikle kabuk skriptleri için geçerlidir.
DocSalvager

8

bir boru kullanabilirsiniz

echo "apple pear orange" | wc

8
Bir boru "bir dosyadan okumak" ile aynı değildir. Örneğin bir boruda geriye doğru arama yapamazsınız, oysa bir dosyada arama yapabilirsiniz.
rbialon

0

Beklediğiniz gibi bir şey kullanmak isteyebilirsiniz. Aşağıdakiler uzaktan bir telnet oturumu açmak, istemini beklemek, veri göndermek, yanıt beklemek, uyku ve çıkış için basit bir örnektir.

#!/usr/bin/expect
spawn telnet localhost 8555
expect "Escape character is '^]'."
send "Hello World\n"
expect "Connection closed by foreign host."
sleep 1
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.