Çıktı yönlendirme özelliğini burada belgeler ve cat ile birlikte nasıl kullanıyorsunuz?


56

Diyelim ki başka bir komuta yönlendirmek veya bir dosyaya yönlendirmek istediğim bir komut dosyası var ( shörnekler için). Bash kullandığımı varsayalım.

Bunu kullanarak yapabilirim echo:

echo "touch somefile
echo foo > somefile" | sh

Neredeyse aynı şeyi kullanarak da yapabilirdim cat:

cat << EOF
touch somefile
echo foo > somefile
EOF

Ama eğer "EOF" u "EOF | sh" ile değiştirirsem, bunun heredokokun bir parçası olduğunu düşünüyor.

Bunu nasıl böylece yapabilirsiniz catbunun keyfi bir konuma borular sonra Stdin'den çıktılar metin ve?


touchOlmadığı sürece, tam olarak ne istiyorsun? sadece girdi dosyasını okuyup stdout ile diğerine yönlendirmek mi?
Rahul Patil

2
@RululPatil elbette işe yaramaz. Heredok daha iyi göstermek için, sadece birden fazla satır ile bir örnek istedim. Ve şu örneğe bakın: echo- Bunun eşdeğerinin ne olacağını merak ediyordum cat.
Strugee

Örneğin, shbirden çok dizeden bir komut dosyası oluşturmak ve onu doğrudan iletmek sh. Q'nuzu, HERE belgesi de dahil olmak üzere birden çok komutun metin çıktısını doğrudan bir komuta geçirmeyi ararken buldum. Ash'in cevabının 2. örneği budur.
Dave X,

Yanıtlar:


91

Bunu yapmanın birden fazla yolu var. En basit olanı şudur:

cat <<EOF | sh
touch somefile
echo foo > somefile
EOF

Başka, bence daha güzel sözdizimi:

(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh

Bu da işe yarar, ancak alt kabuk olmadan:

{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh

Daha fazla varyasyon:

cat <<EOF |
touch somefile
echo foo > somefile
EOF
  sh

Veya:

{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF

Bu arada, catsorunuzun kullanımının başka bir şey için yer tutucusu olmasını bekliyorum . Eğer değilse, çıkarın, şöyle:

sh <<EOF
touch somefile
echo foo > somefile
EOF

Bu basitleştirilmiş olabilir:

sh -c 'touch somefile; echo foo > somefile'

veya:

sh -c 'touch somefile
echo foo > somefile'

Boru yerine çıktı yönlendirmesi

sh >out <<EOF
touch somefile
echo foo > somefile
EOF

catEşdeğerini almak için kullanarak echo test > out:

cat >out <<EOF
test
EOF

Birden Çok Burada Belge

( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2

Bu çıktı üretir:

hi
---
there

İşte neler oluyor:

  • Kabuk, içindeki ( ... )komutları bir alt kabukta görür ve çalıştırır.
  • Kedi ve eko yeterince basit. cat <&3Dosya tanıtıcı ile kediyi çalıştırmak için diyor (fd) 0 (stdin) fd 3'ten yönlendirildi; Başka bir deyişle, fd 3'ün girişini kesin.
  • Başlamadan önce, (...)kabuk buradaki iki belgeyi görür ve fd 0 ( <<EOF) ve fd 3 ( 3<<EOF2) 'i boruların okuma tarafı ile yönlendirir ve yerine koyar
  • İlk komut başlatıldığında, kabuk EOF ulaşana kadar stdin değerini okur ve bunu ilk borunun yazma tarafına gönderir
  • Sonra, EOF2 ve ikinci borunun yazma tarafı ile aynı şeyi yapar

ikinci-son örneğe bakıldığında, boru yerine stdout yönlendirmesine sahip bir örnek verebilir misiniz?
strugee

Cevabı bir yönlendirme örneği ile değiştirdim; Düzenlemek istediğiniz form bu mu? Olmazsa, netleştirmek için bu kısmın ilk satırını verebilir misiniz?
kül

1
Kabuğun bunu nasıl işlediğini anlamanıza yardımcı olabilir. Komut satırını değerlendirdiğinde ve << EOF'yi bulduğunda, standart girdiden yalnızca EOF olan bir satır bulunana veya girişin sonuna kadar okur. Orijinal komut satırında henüz işlenmemiş olan her şey daha sonra işlemeye devam eder. Dolayısıyla, örneğin, böyle bir şey yapmak mümkündür: (cat; echo ---; exec <&3; cat) <<EOF 3<<EOF2 >outve sonra bu komut girişini iki satırda iki satırla birlikte verin.
kül

Kabuk işlemenin açıklaması ilginçti ama başımın üstünde :) Bilmek istediğim şey, cateşdeğer echo test > outbir şeydi, heredoc kullanarak. Oysa verilen örneğiniz, borunun sonuna bir yönlendirme ekledi.
strugee

1
@OlivierDulac - Cevabına çoklu heredoc örneği ekledim.
kül

1

Sadece kullanmanın meowtıpkı kadar geçerli olduğunu belirtmek istiyorum EOF.

Bu komut Meow!dosyası adlı bir dosyaya eklenir cat:

#!/bin/sh
cat <<meow>> cat
Meow!
meow

Farklı kaydet catsve çalıştırılabilir hale getir chmod +x cats, sonra çalıştır ./cats:

$ ./cats
$ cat cat
Meow!
$ ./cats
$ cat cat
Meow!
Meow!

Açıklama:

  • cat <<meowolduğu burada belge sözdizimi. Komut dosyasına bu satırı izleyen metin bloğunu dizeyle karşılaşıncaya kadar seçmesi talimatını verir meow. İçerikler daha sonra çıkarılacaktır (veya birlikte yayınlanacaktır).
  • >> catBorular adlı dosyaya cat.
  • >Bunun yerine kullanmak >>, dosyaya eklemek yerine dosyanın üzerine yazar.
  • Meow!Bu belgenin içeriği .
  • meowBu belgenin son göstergesi . İçindekiler, kullanımıyla >>eklenmiştir cat.

Hem stdout'a hem de bir dosyaya yönlendirme:

İstediğiniz boruları yapmak için burada belge gerekmez.

cathem metin çıkarıp hem de metni geçemez, ancak istediğiniz teeşey için mükemmel bir eşleşme olabilir:

echo echo | tee tee

Bu hem dizgenin çıktısını hem de isimli bir dosyaya echoyazacaktır .echotee

catGereksinimin bir parçasıysa , çıktıyı aşağıdakilerden biriyle de geçebilirsiniz :

echo echo | tee tee | cat </dev/stdin

Ya da sadece:

echo echo | tee tee | cat

Dosyanın içeriği:

$ cat tee
echo

1
Bu soruya gerçekten cevap vermiyor. Ayrıca >son merminizin ima ettiği gibi borular oluşturmaz.
08’de

2
@strugee, >boruları oluşturabilir zshaynı fd gibi bir kaç kez yeniden yönlendirildiğinde echo foo >&1 > teeveya echo foo > tee | cat, burada zsh, bir iç uygular teeçıkışını beslemek için echohem catve teedosya.
Stéphane Chazelas

Soruyu daha iyi cevaplamak için cevabım güncellendi.
Alexander
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.