Yeniden yönlendirmeyi nasıl kullanacağımı nasıl hatırlayabilirim?


40

ne biliyorum

  program > /dev/null 2>&1 

yapar. Bu çıktı yönlendirir /dev/nullve 2>&1çıkış gönderildiği aynı yerde hata çıkışını yönlendirmek için araçlar.

Benim sorunum, her zaman google'a gitmem gerek çünkü asla hatırlamıyorum.

Yani, deneyin &2>1, 1>2&, 1>&2bunu google kadar ... Her kombinasyonunu deneyin ...

Kolayca hatırlamanın püf noktası nedir?


Aynı sorunu yaşıyorum, bu yüzden "uzun" şekilde yapıyorum - her ikisini de yönlendirin program 1> /dev/null 2>/dev/null. Bazı zamanlar gerçekte neler olup bittiğini görmek için stdoutve stderrbirlikte karıştırmanız gerekebilir - bir dosyaya yönlendirilen karmaşık bir derleme işleminin çıktısı gibi. Bu durumda, googling sonunda
bitiriyorum

Yanıtlar:


20

Çıktı, hatadan daha iyidir, bu nedenle önce gelir (1'e 2).

>kısaca 'gider'. Sol tarafta göndermek istediğim, sağ tarafta göndermek istediğim yer. 'Nerede' (neredeyse) her zaman bir dosya olduğundan,

program > /dev/null 2>1

1 adındaki bir dosyaya yönlendirilir. Böylece, ve işareti (&)dosya tanımlayıcısını değiştirir.

Maalesef, kendime ait bir anımsatıcıya rastlamadım ya da geliştirmedim, ama ilk öğrendiğimde * nix, iyi çalışmanın mantıklı yolunu buldum. Birkaç geçişin ardından, ikinci doğa olur.


İlk cümlenin bana bir şey ifade etmiyor. stdoutdosya tanıtıcısı 1, stderr2'dir. Yani, "hata", "çıktı" dan önce gelir.
Warren Young

Bu cümle hangi dosya tanımlayıcısının stdoutve başvuruda bulunduğunu hatırlamak için bir hatırlatmadır stderr.
gvkv

Tamam, ama yine de kafa karıştırıcı görünüyor, çünkü asıl soru "2> & 1" çeşidindeki karakterlerin sırasını hatırlamaya çalışmakla ilgili.
Warren Young

9

Bir hile sadece 1 = standart çıktı, 2 = standart hata olduğunu hatırlamak içindir. Yani:

2>&1= standart hata akışı standart çıktı akışına giriyor.
1>&2= tam tersi.

Daha önce C benzeri bir dilde programladıysanız, ampersand'ı ( &) hatırlamak kolaydır . Bunu, mevcut dosya tanımlayıcısının "adres" e atıfta bulunmayı düşünüyorum, böylece dosyanın kendisini değiştirmez veya yenisini oluşturmazsınız.


7

&Düğümü görmek yardımcı olabilir: 2'nin çıktısını alarak ne yapmak istediğinizi düşünün 2>, ve 1 ile birleştirin,2>&1


2
Sadece "ikisi bir ve bir" ifadesini ezberledim. Anımsatıcınız bir cümle ya da düğüm olsa da, birinin olması gerçekten yardımcı olacaktır.
Tim Kennedy

5

Aslında, hangi kabuğu kullandığına bağlı. Bash genellikle çok bağışlayıcıdır ve sadece:

program &> file

5

Bu üç seçeneği göz önünde bulunduralım:

program  2>1
program  2>1& 
program  2>&1

İlki, stderr dosyasını "1" adında bir dosyaya gönderir: sonuçta, bash bir dosyaya yönlendirmeyi bekler.

İkincisi de aynı dosyaya yönlendirir, ancak programarka planda çalışır : bu bir sonun ne &anlama geldiğidir.

Bu üçüncü olasılığı, bash evreninde bir dosya tanıtıcısına yönlendirmek için mantıklı olan tek şey olarak bırakıyor.

Hangisi 0, 1, 2 arasında hangisi olduğunu hatırlıyorum? Bir bilgisayarı konsoldan çalıştırmayı düşünün. İlk önce bir şeyler yazmalısınız (0 = stdin). Sonra çıktıyı görüyorsunuz (1 = stdout). Son olarak ve sadece bir şeyler ters giderse, stderr (2) 'yi görürsünüz.


1

Duvar kağıdına çiz.

Şimdi, ciddiyim, bu ve unutmaya devam ettiğim diğer temel şeyler, bu yüzden geliştirdiğim ve günlük kullandığım bir uygulamaya hızlı bir ipucu menüsü ekledim. Bir denemek ya da not tutmak için gnote gibi bir şey kullanmak isteyebilirsiniz.


1

Bash kabuğu ile ilgili olarak hatırlamak için en iyi yolu ne olduğunu anlamaktır.
Tek yapmak istediğiniz komutu nasıl doğru alacağımı hatırlamaksa, deneyebilirsiniz

program > /results 2> /results

Neler olup bittiği ve hatırlanması kolay olan çok açık ve güzel yani

  • 1 STDOUT gidiyor /results
  • 2STDERR da gidiyor doğrudan etmek/results

Sorun şu ki, beklediğiniz gibi çalışmıyor. aşağıdakileri göz önünde bulundur:

dosya: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

ve komut çalıştırmak

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

sonra

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

burada ne oldu?
Benim anlayış STDERR işaret yönlendirme bash kurulduğundan doğrudan dosyaya /tmp/resultsnedeniyle doğasının >2 şey yapar ki

  1. normalde yeni bir dosya oluşturun - bu durumda, bash, çıktı üretildiği sırada bash bu rutinden geçerken fırsat geçti.
  2. Dosyanın başına doğrudan yerleştirin. ve aynen >>öyle değil .

Yani bu durumda STDERR, doğrudan /tmp/resultsSTDOUT çıkışını geçersiz kılmanın başlangıcına yerleştirir .
Not: Eğer eklerseniz >>eskiden muhtemelen bu sözdiziminden kurtulabilirsiniz.
Ancak sorunu düzeltmek için - STDERR'yi doğrudan dosyaya yönlendirmek için değil, STDERR'nin çıkışını STDOUT akışına birleştirmek için ihtiyacınız var, bu yüzden bir çarpışma elde edemezsiniz.
Operatör 2>&1operatörünü kullanarak bunu başarır

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

&Adlı bir dosyadan ayırt etmek bash sağlayan 1ve 1dosya tanımlayıcı.
Bana göre ifadenin 2>&1kendisi tam olarak ne olduğunu açıklıyor - STDERR STDOUT'un kendisine yönlendiriliyor - ve sadece /tmp/resultssonuçta geliyor çünkü STDOUT'un işaret ettiği yer (neredeyse bir yan etki gibi).
Kılavuzların 2>&1birçoğunun iddia ettiği şeyin aksine, STDERR'yi hiç STDOUT'un işaret edildiği yere gönderir. Eğer bu doğru olsaydı - hala üzerine yazma probleminiz olurdu.

Daha fazla bilgi için bkz. - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

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.