Dikkat edilmesi gereken ilk şey, amacınıza ve kabuğunuza bağlı olarak birkaç yol olmasıdır, bu nedenle bu, birden fazla yönün hafifçe anlaşılmasını gerektirir. Ayrıca, aşağıdaki gibi belirli komutlar time
ve strace
çıktıyı varsayılan olarak stderr'ye yazın ve bu komuta özgü bir yeniden yönlendirme yöntemi sağlayabilir veya vermeyebilir
Yeniden yönlendirmenin ardındaki temel teori, kabuk tarafından oluşturulan bir işlemin (kabuk yerleşik değil, harici bir komut olduğu varsayılarak) oluşturulmasıdır fork()
ve execve()
syscalls ve bundan önce başka bir syscall olur dup2()
daha önce gerekli yönlendirmeleri gerçekleştirir execve()
olur. Bu anlamda yönlendirmeler üst kabuktan devralınır. Bu m&>n
ve m>n.txt
kabuğun nasıl gerçekleştirileceği hakkında bilgi verin open()
ve dup2()
syscall (ayrıca bkz. Girdi yeniden yönlendirmesi nasıl çalışır?, Yönlendirme ve kanal arasındaki fark nedir, ve Çıktı yönlendirmesinde & tam olarak ne anlama geliyor )
Kabuk yönlendirmeleri
En tipik, via 2>
içinde Bourne benzeri kabuklar, mesela dash
(sembolik olarak bağlı olan /bin/sh
) ve bash
birincisi varsayılan ve POSIX uyumlu kabuk, diğeri ise çoğu kullanıcının etkileşimli oturum için kullandığı kabuktur. Sözdizimi ve özelliklerde farklılık gösterirler, ancak neyse ki bizim için hata akışı yeniden yönlendirmesi aynı şekilde çalışır (hariç &>
standart olmayan). Csh ve türevleri durumunda, stderr yönlendirmesi orada pek işe yaramıyor.
Geri dönelim 2>
parça. Dikkat edilmesi gereken iki önemli şey: >
bir dosyayı açtığımız yönlendirme operatörü anlamına gelir ve 2
tamsayı, stderr dosya tanımlayıcısı anlamına gelir; aslında bu, kabuk dili için POSIX standardının yönlendirmeyi tam olarak nasıl tanımladığıdır bölüm 2.7:
[n]redir-op word
Basit için >
yönlendirme, 1
tamsayı için ima edilir stdout
, yani. echo Hello World > /dev/null
sadece aynı echo Hello World 1>/dev/null
. Tamsayı veya yeniden yönlendirme işlecinin alıntılanamayacağını unutmayın, aksi halde shell bunları tanımıyor ve bunun yerine değişmez metin dizesi olarak ele alıyor. Boşluklara gelince, integer'ın yeniden yönlendirme operatörünün hemen yanında olması önemlidir, ancak dosya yeniden yönlendirme operatörünün yanında olabilir veya olmayabilir, yani. command 2>/dev/null
ve command 2> /dev/null
gayet iyi çalışacaktır.
Kabuktaki tipik komut için biraz basitleştirilmiş sözdizimi şöyle olacaktır
command [arg1] [arg2] 2> /dev/null
Buradaki hile, yönlendirmenin herhangi bir yerde görünebilmesidir. Bu ikisi de 2> command [arg1]
ve command 2> [arg1]
geçerlidirler. Bunun için dikkat edin bash
kabuk, orada var &>
hem stdout hem de stderr akışlarını aynı anda yeniden yönlendirmenin yolu, ancak yine de - bash'a özgüdür ve komut dosyalarının taşınabilirliği için çabalıyorsanız, çalışmayabilir. Ayrıca bakınız Ubuntu Wiki ve >>&Amp; ve 2 &1 arasındaki fark nedir.
Not: Bu >
yönlendirme işleci buduyor bir dosya ve dosya varsa üzerine yazar. Bu 2>>
eklemek için kullanılabilir stderr
dosyalamak.
Eğer fark ederseniz, >
tek bir komut içindir. Komut dosyaları için, tüm komut dosyasının stderr akışını dışarıdan olduğu gibi yönlendirebiliriz myscript.sh 2> /dev/null
ya da faydalanabiliriz exec yerleşik. Yerleşik exec, etkileşimli olarak veya komut dosyası aracılığıyla, tüm kabuk oturumu için akışı yeniden bağlama gücüne sahiptir. Aşağı yukarı
#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file
Bu örnekte, günlük dosyası şunları göstermelidir stat: cannot stat '/etc/non_existing_file': No such file or directory
.
Başka bir yol da işlevlerdir. Olarak külkedisi cevabında belirtildiği gibi, zaten eklenmiş yönlendirme ile işlev bildirimi yazabiliriz, yani
some_function(){ command1 command2} 2> my_log_file.txt
Yalnızca stderr'ye yazma komutları
Aşağıdaki gibi komutlar time
ve strace
çıktılarını varsayılan olarak stderr'ye yazın. Durumunda time
komut, tek geçerli alternatif, tüm komutun çıktısını yeniden yönlendirmektir, yani
time echo foo 2>&1 > file.txt
alternatif olarak, çıktıyı ayırmak istiyorsanız senkronize liste veya alt kabuk yeniden yönlendirilebilir (gösterildiği gibi ilgili gönderi ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Diğer komutlar, örneğin strace
veya dialog
stderr'yi yönlendirmek için araçlar sağlayın. strace
var -o <filename.txt>
çıktı yazılması gereken dosya adını belirtmeyi sağlayan seçenek. Her alt işlem için bir metin dosyası yazmak için bir seçenek de vardır strace
görür. Bu dialog
komut, metin kullanıcı arayüzünü stdout'a yazar, ancak çıktıyı stderr'ye yazar, böylece çıktısını değişkene kaydet ( çünkü var=$(...)
ve boru hatları sadece stderr alır) dosya tanımlayıcılarını değiştirmemiz gerekir
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
ancak ek olarak, var --output-fd
bayrağı da kullanabiliriz. Adlandırılmış yöneltmeler yöntemi de vardır. Bu konuyla ilgili bağlantılı yazıyı okumanızı tavsiye ederim. dialog
neler olup bittiğinin ayrıntılı açıklaması için komuta edin.