"Komut 1> dosya.txt 2> dosya.txt`'nin davranışı neden" komut 1> dosya.txt 2> & 1 "den farklıdır?


20

Stdout ve stderr öğelerini aynı dosyaya yeniden yönlendirmek istediğinizde command 1>file.txt 2>&1, veya tuşunu kullanarak bunu yapabilirsiniz command &>file.txt. Ama neden command 1>file.txt 2>file.txtyukarıdaki iki komuttan farklı davranışı var ?

Aşağıdaki bir doğrulama komutudur.

$ cat redirect.sh
#!/bin/bash

{ echo -e "output\noutput" && echo -e "error" 1>&2; } 1>file.txt 2>&1
{ echo -e "output\noutput" && echo -e "error" 1>&2; } 1>file1.txt 2>file1.txt
{ echo -e "error" 1>&2 && echo -e "output\noutput"; } 1>file2.txt 2>file2.txt
{ echo -e "output" && echo -e "error\nerror" 1>&2; } 1>file3.txt 2>file3.txt
{ echo -e "error\nerror" 1>&2 && echo -e "output"; } 1>file4.txt 2>file4.txt

$ ./redirect.sh

$ echo "---file.txt---"; cat file.txt;\
echo "---file1.txt---"; cat file1.txt; \
echo "---file2.txt---"; cat file2.txt; \
echo "---file3.txt---"; cat file3.txt; \
echo "---file4.txt----"; cat file4.txt;
 ---file.txt---
output
output
error
---file1.txt---
error

output
---file2.txt---
output
output
---file3.txt---
error
error
---file4.txt----
output
rror

Sonuçlar göründüğü kadarıyla, çalıştırdığınızda ikinci yankı dizesinin ilk yankı dizesinin üzerine yazdığı anlaşılıyor command 1>file.txt 2>file.txt, ancak neden olacağını bilmiyorum. (Bir yerde referans var mı?)

Yanıtlar:


43

İki şeyi bilmeniz gerekir:

  • Açık bir dosya tanıtıcı bir işlemin uygulama modu tarafına bilinen bir şekilde bilinen bir iç çekirdek nesnesi başvuran dosya bilgi açık bir dosya bir örneğidir. Dosya başına birden çok dosya açıklaması ve bir dosya açıklamasını paylaşan birden fazla dosya tanımlayıcısı olabilir.
  • Geçerli dosya konumu bir bir özelliğidir dosya açıklaması . Bu nedenle, birden fazla dosya tanımlayıcısı tek bir dosya tanımıyla eşleşirse, bunların tümü aynı geçerli dosya konumunu paylaşır ve bu tür bir dosya tanımlayıcısı kullanılarak yürürlüğe konulan dosya konumunda yapılan bir değişiklik, bu tür diğer dosya tanımlayıcılarının tümünü etkiler.

    Bu tür değişiklikler çağrı işlemleri ile canlandırılır read()/ readv(), write()/ writev(), lseek()ve benzeri sistem çağrıları. echoKomut çağrıları write()/ writev()tabii ki.

Peki bu şu:

  • command 1>file.txt 2>&1kabuk yalnızca bir kez dosya açtığından yalnızca bir dosya açıklaması oluşturur. Kabuk, hem standart çıktıyı hem de standart hata dosyası tanımlayıcılarını bu tek dosya tanımıyla eşleştirir. Bu kopyalar standart hata üzerine standart çıktıyı. Bu nedenle, her iki dosya tanımlayıcı üzerinden bir yazma, paylaşılan geçerli dosya konumunu taşır: her yazma, önceki yazma ortak dosya tanımından sonra gider. Gördüğünüz gibi echokomutların sonuçları birbirinin üzerine yazmıyor.
  • command 1>file.txt 2>file.txtiki dosya açıklaması oluşturur , çünkü kabuk iki açık yönlendirmeye yanıt olarak aynı dosyayı iki kez açar. Standart çıktı ve standart hata dosyası tanımlayıcıları iki farklı dosya tanımıyla eşleşir ve daha sonra aynı tek dosyayla eşleşir. İki dosya açıklaması tamamen bağımsız geçerli dosya konumlarına sahiptir ve her yazma işlemi aynı dosya açıklamasında önceki yazma işlemine derhal gider. Ve sonucu görebileceğiniz gibi, biri aracılığıyla yazılanlar, diğeriyle yazılanların üzerine, yazmaları hangi sırada yürüttüğünüze göre çeşitli şekillerde yazabilirler.

daha fazla okuma


1
Olmalı açık dosya açıklaması ziyade dosya açıklaması . Daha çok dosyanın nasıl açıldığının kaydı hakkındadır. En azından POSIX, Linux, Solaris ve GNU belgeleri tarafından kullanılan terminoloji budur.
Stéphane Chazelas

16

Kullanılması >, dosyanın üzerine yazmasını söyler. İki farklı işlemde dosyaya stdout ve stderr yazdığınızdan, sonuncusu üzerine yazılır.

Yapabilirsin:

command 1>>file.txt 2>>file.txt

veya

command &>file.txt Yalnızca bash v4 ve üstü.

>> dosyaya önceki işlemlerin çıktısının yerine geçmeyeceğini söyler.

&> yazmanın daha kolay bir yolu 2>&1


2
neden yok ls 1>&0ve ls 0>&0hala ls çıkışını gösteriyor?
Yvain

>>İşleri kullanmanın şaşırttı . Bunun neden bağımsız ofsetlerle iki dosya açıklaması sorunu yok? @JdeBP, biliyor musun? Bir dosyayı ekleme modunda açmanın yazma modunda açmaya, son konuma bakmaya ve daha sonra aramaya izin vermemeye eşdeğer olduğunu düşündüm.
JoL

4
@jlmg: Ekleme modu dosyaları aranabilir, ancak her yazmanın sonuna ima edilen bir arama eklenir. Bu zımni aramanın atomik olup olmadığı benim için daha az açık.
Kevin

1
Bu tamamen takip eden soruya bağlıdır. Bu gibi olanlar, cevabın eksik olduğunu gösterir. Ve insanların cevabı tam olarak bilmek istemeden takip sorularına bakmaları pek olası değildir. Bu nedenle, soruların bu şekilde takip edilmesinin, yinelenen bilgilerle cevapları olması ve böylece kopyalar olarak kapanması muhtemeldir.
trlkly

1
@Kevin, tamamen POSIX uyumlu dosya sistemlerinde, örtük O_APPEND araması atomiktir. Bununla birlikte, her dosya sistemi ilgili anlambilimi düzgün bir şekilde uygulamıyor - örneğin, NFS (en azından v3 ve öncesi - v4'te net değilim), ilgili protokolün tel protokolüne dönüştürülmediğini, bu nedenle sunucunun istemcinin bir dosyayı açıp açmadığını bilmenin hiçbir yolu yoktur O_APPEND.
Charles Duffy
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.