Kabukta “2> & 1” ne anlama geliyor?


2284

Ben birleştirmek istiyorsanız Unix kabuğu, stderrve stdoutiçine stdoutdaha fazla manipülasyon için dere, benim komuta sonuna aşağıdaki ekleyebilirsiniz:

2>&1

Yani, headçıktı almak istiyorsanız g++, böyle bir şey yapabilirsiniz:

g++ lots_of_errors 2>&1 | head

sadece ilk birkaç hatayı görebiliyorum.

Bunu her zaman hatırlamakta zorlanıyorum ve sürekli bakmam gerekiyor ve bunun nedeni, bu özel hile sözdizimini tam olarak anlamadığım için.

Birisi bunu parçalayıp karakteri karakter olarak açıklayabilir 2>&1 mi?


50
@dbr Sadece bash olduğunu sanmıyorum - bunun bir bourne kabuğu şey olduğuna inanıyorum; dolayısıyla sh, bash, ksh, kül, çizgi, vb.
silahlar

8
Bu, POSIX uyumlu kabukları veya kısaca POSIX kabuğunu açıklayan yönlendirme paragrafının bir parçasıdır. ksh, örneğin bir POSIX kabuğudur. Bakınız: pubs.opengroup.org/onlinepubs/009695399/utilities/…
jim

12
Bu yapı Windows üzerinde de çalışır.
Vadzim

2
Genellikle iyi yapıyor 2>&1daha 2> / dev / null ;-)
F. Hauri

11
Zsh kullanıyorsanız |& kısaca bunun söyleneceğini düşündüm 2>&1 |. Bunun diğer bourne benzeri kabuklar için geçerli olup olmadığı veya sadece zsh özelliği olup olmadığı hakkında konuşamam.
Aralık'ta chrixian

Yanıtlar:


2556

Dosya tanımlayıcı 1 standart çıktıdır ( stdout).
Dosya tanımlayıcı 2 standart hatadır ( stderr).

İşte bu yapıyı hatırlamanın bir yolu (tamamen doğru olmasa da): ilk başta, 2>1yönlendirmek stderriçin iyi bir yol gibi görünebilir stdout. Ancak, aslında " stderradlı bir dosyaya yönlendirme" olarak yorumlanacaktır 1. &aşağıdakilerin dosya adı değil dosya tanımlayıcısı olduğunu belirtir. Yani yapı haline gelir: 2>&1.


281
ama o zaman öyle değil &2>&1mi?
dokaspar

319
@Dominik: Hayır, &yeniden yönlendirme bağlamında yalnızca "dosya tanımlayıcı" anlamına gelir. Yazma ve " arka planda çalıştır, sonra komutu çalıştır ve stdout'unu stdout'una yönlendir " command &2>&şeklinde ayrıştırılır . command &2>&1command2
Adam Rosenfield

15
Neden böyle gizli şeyler seçtiler? Sadece merak.
CommaToast

81
Fakat stderr'i '& 1' adlı bir dosyaya nasıl yönlendirirsiniz?
Martín Fixman

120
@Martin:2>'&1'

632
echo test > afile.txt

stdout'u yeniden yönlendirir afile.txt. Bu yapmakla aynı

echo test 1> afile.txt

Stderr'ı yeniden yönlendirmek için şunları yaparsınız:

echo test 2> afile.txt

>& bir akışı başka bir dosya tanımlayıcısına yönlendirmek için kullanılan bir sözdizimidir - 0 stdin, 1 stdout ve 2 stderr'dir.

Aşağıdaki işlemleri yaparak stdout'u stderr'a yönlendirebilirsiniz:

echo test 1>&2 # or echo test >&2

Ya da tam tersi:

echo test 2>&1

Kısacası ... 2>stderr'ı (belirtilmemiş) bir dosyaya &1yönlendirir, stderr'ı stdout'a yönlendirir.


5
bu sana bir anlam ifade ediyor mu, java ... 2&1 >> data.logmeslektaşımdan birinin bunu yaptığını gördüm?
Thang Pham

5
@Harry o bash olmayan bir kabuk ya da bir yazım hatası ya gibi görünüyor .. cmd 2>&1 >> somefile.logwill ekleme stdout / stderr bir dosyaya - bu birlikte, temelde yukarıda aynı şey >> fileeklerine
dbr

73
@dbr cmd 2>&1 >>filestderr dosyasını dosyaya yönlendirmez, ancak cmd >> file 2>&1yapar. Sipariş önemlidir. İlk durumda, stderr kabuğun stdout'una yönlendirilir (muhtemelen komut etkileşimli olarak girilirse tty) ve sonra stdout dosyaya yönlendirilir. İkinci durumda, stdout dosyaya yönlendirilir ve sonra stderr aynı yere yönlendirilir.
William Pursell

2
Yukarıdaki cevabı seviyorum, ama bu daha net bir dokunuş olabilir. "2> & 1" stderr'ı stdout hedefine yönlendirir. Yani "ls -l >> directoryContents 2> & 1" gibi bir şey varsa Sonuç indexContents adlı bir dosya olacak ve buna ekli çalışma dizininin içeriği olacaktır. Yürütmede herhangi bir hata varsa: hata iletileri, meydana geldikçe, directoryContents dosyasına da eklenir.
Max West

1
0(or 1,2)>&0(or 1,2)çıkışını kontrol etmek için bir seçenek gibi? İle echo test >test.log 2>&1aynı mı echo test 2>&1 >test.log?
Simin Jie

318

Yönlendirme hakkında bazı püf noktaları

Bununla ilgili bazı sözdizimi özelliğinin önemli davranışları olabilir. Yönlendirmeler, hakkında bazı küçük örnekler vardır STDERR, STDOUTve argümanlar sipariş .

1 - Üzerine mi yazıyor yoksa eklensin mi?

Sembol >ortalama yeniden yönlendirme .

  • >tamamlanmış bir dosya olarak göndermek , varsa hedefin üzerine yazmak anlamına gelir ( daha sonra # 3'tekinoclobber bash özelliğine bakın ).
  • >>Ortalama ek olarak gönderme için exist eğer hedef bilgisini ekleyecektir.

Her halükarda, dosya mevcut değilse oluşturulur.

2 - Kabuk komut satırı sıraya bağlıdır !!

Bunu test etmek için , her iki çıktıda da bir şey gönderecek basit bir komuta ihtiyacımız var :

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

( /tntElbette adında bir dizininiz olmaması bekleniyor ;). Peki, bizde var !!

Bakalım:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

Son komut satırı STDERRkonsola atıyor ve beklenen davranış gibi görünmüyor ... Ama ...

Bir çıktı, diğeri ya da her ikisi hakkında bir post filtre uygulamak istiyorsanız :

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

Bu paragraftaki son komut satırının, önceki yazımdakiyle tamamen aynı olduğuna dikkat edin, burada yazdım , beklenen davranış gibi görünmüyor (bu nedenle, bu beklenen bir davranış olabilir).

Her iki çıktıda da farklı işlemler yapmak için yönlendirmelerle ilgili küçük hileler var :

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Not: &9tanımlayıcı kendiliğinden gerçekleşir ) 9>&2.

Zeyilname: nota! Yeni sürümü ile( >4.0) bu tür şeyleri yapmak için yeni bir özellik ve daha seksi sözdizimi var:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

Ve son olarak böyle bir basamaklı çıktı biçimlendirmesi için:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Zeyilname: nota! Her iki yönde de aynı yeni sözdizimi:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

STDOUTBelirli bir filtreden geçtiği yerde , STDERRdiğerine ve son olarak her iki çıkış da üçüncü bir komut filtresinden geçer.

3 - noclobberSeçenek ve >|sözdizimi hakkında bir kelime

Üzerine yazmakla ilgili :

İken set -o noclobbertalimat bash için değil varolan herhangi dosyanın üzerine, >|sözdizimi, bu sınırlama geçmesine izin:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

Her seferinde dosyanın üzerine yazılır:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Şununla geç >|:

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

Bu seçeneğin ayarını kaldırmak ve / veya önceden ayarlanmışsa sormak.

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - Son hile ve daha fazlası ...

Belirli bir komuttan her iki çıktıyı yeniden yönlendirmek için doğru bir sözdiziminin olabileceğini görüyoruz:

$ ls -ld /tmp /tnt >/dev/null 2>&1

bu özel durum için bir kısayol sözdizimi vardır: &>... veya>&

$ ls -ld /tmp /tnt &>/dev/null

$ ls -ld /tmp /tnt >&/dev/null

Not: Varsa 2>&1, 1>&2doğru bir sözdizimidir:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b- Şimdi düşünmenize izin vereceğim:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4c- Daha fazla bilgi edinmek istiyorsanız

İnce kılavuzu okuyarak okuyabilirsiniz:

man -Len -Pless\ +/^REDIRECTION bash

içinde konsol ;-)


5
Daha fazla okuma: Eğer bunu
beğendiyseniz


130

Yönlendirme hakkındaki bu parlak gönderiyi buldum: Yönlendirmeler hakkında her şey

Hem standart çıktıyı hem de standart hatayı bir dosyaya yönlendirin

$ command &> dosya

Bu tek astar, &>operatörü her iki çıktı akışını (stdout ve stderr) komuttan dosyaya yönlendirmek için kullanır . Bu, Bash'in her iki akışı da aynı hedefe hızlı bir şekilde yönlendirmek için kısayoludur.

Bash her iki akışı da yönlendirdikten sonra dosya tanımlayıcı tablosu şöyle görünür:

Resim açıklamasını buraya girin

Gördüğünüz gibi, hem stdout hem de stderr şimdi işaret ediyor file. Böylece stdout ve stderr'a yazılan her şey yazılır file.

Her iki akışı da aynı hedefe yönlendirmenin birkaç yolu vardır. Her akışı birbiri ardına yönlendirebilirsiniz:

$ command> dosya 2> & 1

Bu, her iki akışı da bir dosyaya yönlendirmenin çok daha yaygın bir yoludur. İlk stdout dosyaya yönlendirilir ve sonra stderr, stdout ile aynı olacak şekilde çoğaltılır. Böylece her iki akış da işaret ediyor file.

Bash birkaç yönlendirme gördüğünde, onları soldan sağa doğru işler. Adımları gözden geçirelim ve bunun nasıl olduğunu görelim. Herhangi bir komutu çalıştırmadan önce, Bash'ın dosya tanımlayıcı tablosu şöyle görünür:

Resim açıklamasını buraya girin

Şimdi Bash ilk yönlendirme> dosyasını işler. Bunu daha önce gördük ve stdout'u dosyaya işaret ediyor:

Resim açıklamasını buraya girin

Sonraki Bash ikinci yeniden yönlendirmeyi görüyor 2> & 1. Bu yönlendirmeyi daha önce görmedik. Bu, dosya tanımlayıcı 2'yi dosya tanımlayıcı 1'in bir kopyası olacak şekilde çoğaltır ve şunu elde ederiz:

Resim açıklamasını buraya girin

Her iki akış da dosyaya yönlendirildi.

Ancak burada dikkatli olun! yazı

komut> dosya 2> & 1

yazmakla aynı şey değildir:

$ command 2> & 1> dosya

Bash'de yönlendirme sırası önemlidir! Bu komut yalnızca standart çıktıyı dosyaya yönlendirir. Stderr yine de terminale yazdıracaktır. Bunun neden olduğunu anlamak için tekrar adımlardan geçelim. Komutu çalıştırmadan önce, dosya tanımlayıcı tablosu şöyle görünür:

Resim açıklamasını buraya girin

Şimdi Bash, soldan sağa yönlendirmeleri işler. Önce 2> & 1 görür, böylece stderr'ı stdout'a çoğaltır. Dosya tanımlayıcı tablosu:

Resim açıklamasını buraya girin

Şimdi Bash ikinci yönlendirmeyi görüyor >fileve stdout'u dosyaya yönlendiriyor:

Resim açıklamasını buraya girin

Burada ne olduğunu görüyor musunuz? Stdout şimdi dosyaya işaret ediyor, ancak stderr hala terminali gösteriyor! Stderr'e yazılan her şey hala ekrana yazdırılıyor! Bu yüzden yönlendirmelerin sırasına çok, çok dikkat edin!

Ayrıca Bash'te,

$ command &> dosya

tam olarak aynıdır:

$ command> & dosya


3
Son "komut" bir sayı ile biterse farklıdır, o zaman bu>&
MM

Çok güzel çizim ve açıklama! "Yinelenen" ifadesinin gerçekten ne anlama geldiğini açıklayabilir misiniz? "Bu [2> & 1], dosya tanımlayıcı 2'yi dosya tanımlayıcı 1'in bir kopyası olacak şekilde çoğaltır." Stderr, stdout'a kopyalanıyor gibi geliyor. Ama eğer durum buysa, aynı zamanda err'i de görmeli miyim /dev/tty0?
HCSF

87

Sayılar, dosya tanımlayıcılarına (fd) karşılık gelir.

  • Sıfır stdin
  • Biri stdout
  • İki stderr

2>&1 fd'yi 2'ye 1 yönlendirir.

Bu, program bunları kullanıyorsa, herhangi bir sayıda dosya tanıtıcı için çalışır.

/usr/include/unistd.hOnları unutursanız bakabilirsiniz :

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

Özel günlük kaydı için standart olmayan dosya tanımlayıcıları kullanan C araçları yazdım, böylece bir dosyaya veya başka bir şeye yönlendirmediğiniz sürece görmüyorsunuz.


58

Bu yapı, standart hata akışını ( stderr) standart çıktının ( ) geçerli konumuna gönderir stdout- bu para birimi sorununun diğer yanıtlar tarafından ihmal edildiği görülmektedir.

Bu yöntemi kullanarak herhangi bir çıktı tutamacını diğerine yönlendirebilirsiniz, ancak çoğunlukla kanal stdoutvestderr işlem için tek bir akım halinde akışları.

Bazı örnekler:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Bu sonuncusu olacağı Not değil doğrudan stderriçin outfile2- ne için yönlendirir stdoutargüman karşılaşıldı zaman (idi outfile1) ve daha sonra yönlendirir stdoutiçin outfile2.

Bu, bazı oldukça karmaşık numaralara izin verir.


5
Her ne kadar bu son örnek daha açık olsa da: foo> outfile2 2> outfile1
Michael Cramer

3
Daha net, evet, ancak bu yeniden yönlendirmenin "konumsal" doğasını göstermez. Örnek, bunu tek bir satırda yapmak genellikle yararlı olmadığından, yöntem yeniden yapılandırılmıştır - yöntem, farklı taraflar yeniden yönlendirmenin farklı bölümlerinden sorumlu olduğunda gerçekten yararlı olur. Örneğin, bir komut dosyası bir bit yeniden yönlendirme yaptığında ve başka bir bitle çalıştırdığınızda.
paxdiablo

5
: Sadece geçen örnek de bu neden ile ilgili vardı uzun ayakta karışıklığı giderir fark some_program 2>&1 > /dev/nullböyle çalışmaz: some_program > /dev/null 2>&1.
snapfractalpop

Son örnek hakkındaki yorumunuz altın harflerine değer :-) Bu yönlendirme argümanlarının konumsal olduğunu hiç düşünmedim ... Bunun bilmesi oldukça önemli.
Nils-o-mat

20

2>&1bir POSIX kabuk yapısıdır. İşte bir belirteç, jeton belirteci:


2: " Standart hata " çıktı dosyası tanımlayıcısı.

>&: Çıktı Dosyası Tanımlayıcı işlecini ( Çıktı Yeniden Yönlendirme işlecinin bir çeşidi) çoğaltın> . Verilen [x]>&[y], dosya tanıtıcı tarafından le belirtilen xçıkış dosya tanımlayıcı bir kopyası olacak şekilde yapılıry .

1" Standart çıktı " çıktı dosyası tanımlayıcı.

İfade 2>&1dosya tanımlayıcısını 1konuma kopyalar 2, bu nedenle 2yürütme ortamında ("standart hata") ile yazılmış tüm çıktılar başlangıçta 1("standart çıktı") ile tanımlanan aynı dosyaya gider .


Daha fazla açıklama:

Dosya Tanımlayıcı : "Dosya erişimi amacıyla açık bir dosyayı tanımlamak için kullanılan işlem başına benzersiz, negatif olmayan bir tam sayı."

Standart çıktı / hata : Kabuk belgelerinin Yeniden Yönlendirme bölümündeki aşağıdaki nota bakın :

Açık dosyalar, sıfır ile başlayan ondalık sayılarla temsil edilir. Mümkün olan en büyük değer uygulama tanımlıdır; ancak, tüm uygulamalar, başvuru tarafından kullanılmak üzere, en az 0 ila 9'u desteklemelidir. Bu numaralara "dosya tanımlayıcılar" denir. 0, 1 ve 2 değerleri özel bir anlama ve geleneksel kullanımlara sahiptir ve bazı yeniden yönlendirme işlemleri tarafından ima edilir; bunlar sırasıyla standart girdi, standart çıktı ve standart hata olarak adlandırılır. Programlar genellikle girdilerini standart girdiden alır ve çıktıyı standart çıktıya yazar. Hata mesajları genellikle standart hata üzerine yazılır. Yeniden yönlendirme işleçlerinden önce, dosya tanımlayıcı numarasını belirtmek için bir veya daha fazla basamak (arada hiçbir karaktere izin verilmez) gelebilir.


19

2, konsolun standart hatasıdır.

1, konsolun standart çıktısıdır.

Bu standart Unix'tir ve Windows da POSIX'i izler.

Örneğin koştuğunda

perl test.pl 2>&1

standart hata standart çıktıya yönlendirilir, böylece her iki çıktıyı birlikte görebilirsiniz:

perl test.pl > debug.log 2>&1

Yürütmeden sonra hatalar dahil tüm çıktıları debug.log dosyasında görebilirsiniz.

perl test.pl 1>out.log 2>err.log

Daha sonra standart çıktı out.log'a ve standart hata err.log'a gider.

Bunları anlamaya çalışmanızı öneririm.


İkinci örnek yanlıştır: sipariş öncelik olarak STDERR yönlendirilir STDOUT , sadece varsayılan STDOUT yazılır debug.log (değil STDERR ) bkz cevabım (paragraf # 2)! Her ikisinin de aynı dosyaya yönlendirilmesini sağlamak için, yönlendirme yönergelerini tersine perl test.pl > debug.log 2>&1
çevirmeniz gerekir

16

Sorunuzu cevaplamak için: Herhangi bir hata çıktısını alır (normalde stderr'a gönderilir) ve standart çıktıya (stdout) yazar.

Bu, örneğin tüm çıktılar için disk belleği gerektiğinde 'daha' ile yardımcı olur. Bazı programlar kullanım bilgilerini stderr'a yazdırmayı sever.

Hatırlamanıza yardımcı olmak için

  • 1 = standart çıktı (programların normal çıktıyı yazdırdığı yer)
  • 2 = standart hata (programların yazdırma hataları)

"2> & 1", stderr'a gönderilen her şeyi, bunun yerine stdout'a işaret eder.

Ayrıca , bu konunun tam olarak ele alındığı yerdeki hata yönlendirme konusunda bu yazıyı okumanızı da tavsiye ederim .


11

Bir programcının bakış açısından, bu tam olarak şu anlama gelir:

dup2(1, 2);

Kılavuz sayfasına bakınız .

Bunun 2>&1bir kopya olduğunu anlamak neden ...

command >file 2>&1

... ile aynı değil ...

command 2>&1 >file

Birincisi her iki akışı da gönderir file, ikincisi hata gönderir stdoutve normal çıktı file.


9

Eğer bir acemi okumak ise bu çok yararlı buldum bu

Güncelleme:
Linux veya Unix Sisteminde programların çıktı gönderdiği iki yer vardır: Standart çıktı (stdout) ve Standart Hata (stderr) .Bu çıktıyı herhangi bir dosyaya yeniden yönlendirebilirsiniz.

Bunu yaptığınız gibi

ls -a > output.txt

Hiçbir şey konsolda yazdırılmaz Tüm çıkışlar (stdout) çıktı dosyasına yönlendirilmez.

Ve çıkmayan herhangi bir dosyanın içeriğini yazdırmayı denerseniz, çıktı, geçerli dizinde bulunmayan test.txt dosyasını yazdırdığınızda olduğu gibi bir hata

cat test.txt > error.txt

olur.

cat: test.txt :No such file or directory

Ancak stdout'u stderr değil bir dosyaya yönlendirdiğimizden error.txt dosyası boş olacaktır.

bu yüzden kabuk dosyaya ne tür çıktı gönderdiğimizi söylemek için dosya tanımlayıcıya ihtiyacımız var (Dosya tanımlayıcı, açık bir dosyayı temsil eden pozitif bir tamsayıdan başka bir şey değildir. Tanımlayıcının benzersiz bir kimlik olduğunu söyleyebilirsiniz) .In Unix / Linux sisteminde 1 stdout ve 2 stderr içindir .

şimdi bunu yaparsanız

ls -a 1> output.txt, output.txt dosyasına Standart çıktı (stdout) gönderiyorsunuz demektir.

ve bunu yaparsanız

cat test.txt 2> error.txt, error.txt dosyasına Standart Hata (stderr) gönderdiğiniz anlamına gelir.

&1dosya tanımlayıcısı 1'in (stdout) değerine başvurmak için kullanılır.

Şimdi nokta 2>&1"Stderr'ı stdout'u yeniden yönlendirdiğimiz yere yönlendir" anlamına geliyor

Şimdi bunu yapabilirsin

cat maybefile.txt > output.txt 2>&1

hem Standart çıktı (stdout) hem de Standart Hata (stderr) output.txt dosyasına yönlendirilir.

İşaret ettiği için Ondrej K.'ye teşekkürler


1
Yalnızca bağlantı yanıtları sorunludur. Bağlantı geçersiz hale gelebilir ve cevabı işe yaramaz hale getirebilir. Her zaman cevabın kendisine yeterli ayrıntı eklemelisiniz.
Ondrej K.

7

İnsanlar, her zaman hatırlamak paxdiablo hakkında 'ın ipucu şimdiki O ... yönlendirme hedefin konumu olan önemli.

2>&1Operatör için kişisel anımsatım şudur:

  • &Anlam olarak düşünün 'and'veya 'add'(karakter bir amperdir - ve değil mi?)
  • Böylece şöyle olur: ' (stdout) ' un zaten / şu anda olduğu 2yere yönlendir (stderr) 1ve her iki akışı da ekle ' .

Aynı anımsatıcı diğer sık ​​kullanılan yeniden yönlendirme için de çalışır 1>&2:

  • &Anlamı düşünün andya da add... (ve işareti hakkında fikir sahibi misiniz, evet?)
  • Böylece şöyle olur: ' (stderr)' in zaten / şu anda olduğu 1yere yönlendir (stdout) 2ve her iki akışı da ekle ' .

Ve her zaman hatırlayın: Eğer (sağdan sola doğru, 'ucundan' yönlendirmeler zincirlerini okumak zorunda değil soldan sağa).


7

Yönlendirme Girişi

Girişin yeniden yönlendirilmesi, adı, dosyanın tanımlayıcısı n'de okunacak sözcüğün genişletilmesinden kaynaklanan dosyanın veya n belirtilmezse, standart girdinin (dosya tanımlayıcısı 0) okunmasına neden olur.

Girişi yeniden yönlendirmek için genel biçim:

[n]<word

Yönlendirme Çıkışı

Çıktının yeniden yönlendirilmesi, adı dosyanın genişletilmesinden kaynaklanan dosyanın dosya tanımlayıcı n üzerine yazmak için açılmasına veya n belirtilmezse standart çıktıya (dosya tanımlayıcı 1) neden olur. Dosya mevcut değilse oluşturulur; eğer varsa sıfır boyutuna kesilir.

Çıktıyı yeniden yönlendirmek için genel biçim:

[n]>word

Dosya Tanımlayıcılarını Taşıma

Yönlendirme operatörü,

[n]<&digit-

dosya tanımlayıcı basamağını dosya tanımlayıcı n'ye veya n belirtilmezse standart girişe (dosya tanımlayıcı 0) taşır. n'ye çoğaltıldıktan sonra rakam kapatılır.

Benzer şekilde, yönlendirme operatörü

[n]>&digit-

dosya tanımlayıcı basamağını dosya tanımlayıcı n'ye veya n belirtilmezse standart çıktıya (dosya tanımlayıcı 1) taşır.

Ref:

man bash

Tip /^REDIRECTiçin bulmak için redirectionbölüm ve daha fazla bilgi edinmek ...

Çevrimiçi bir sürüm burada: 3.6 Yönlendirmeler

Not:

Çoğu zaman, manLinux öğrenmek için güçlü bir araç oldu.


6

Kaydıyla /foosisteminizde mevcut değildir ve /tmpdoes ...

$ ls -l /tmp /foo

içindekileri /tmpyazdıracak ve/foo

$ ls -l /tmp /foo > /dev/null

için içeriğini gönderecek ve /tmpiçin /dev/nullbir hata mesajı yazdıracak/foo

$ ls -l /tmp /foo 1> /dev/null

tamamen aynı şeyi yapacak (not 1 )

$ ls -l /tmp /foo 2> /dev/null

içeriğini yazdıracak /tmpve hata mesajını/dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

hem listeyi hem de hata mesajını /dev/null

$ ls -l /tmp /foo > /dev/null 2> &1

stenografi


5

Bu, hatayı stdout'a veya terminale geçirmeye benzer.

Yani, cmdbir komut değildir:

$cmd 2>filename
cat filename

command not found

Hata dosyaya şu şekilde gönderilir:

2>&1

Terminale standart hata gönderilir.


1

Giriş için 0, stdout için 1 ve stderr için 2.

Bir ipucu : somecmd >1.txt 2>&1doğru, hiçbir etkisi olmadan somecmd 2>&1 >1.txttamamen yanlış !


1

unix_commands 2>&1

Bu, terminale hata yazdırmak için kullanılır.

Aşağıda süreç gösterilmektedir

  • Hatalar üretildiğinde, &2standart hata akımının 2başvurduğu standart hata belleği adresi "tampon" a yazılır .
  • Çıkış üretildiğinde, &1standart çıkış akımının 1referans aldığı standart çıkış belleği adresi "tampon" a yazılır .

Bu nedenle unix_commandsstandart hata akışını alın 2ve >akışı (hataların) standart çıkış belleği adresine yönlendirin &1, böylece terminale aktarılır ve yazdırılır.

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.