bash: -x günlüklerini dosyaya ayarla


18

set -xAyrıntılı / hata ayıklama çıktısı ile bir kabuk komut dosyası var:

#!/bin/bash

set -x
command1
command2
...

Çıktı şöyle görünür:

+ command1
whatever output from command1
+ command2
whatever output from command2

Benim sorunum kabuk çıkışı (neden olduğu set -x) komutların çıktısı ile karıştırılır (stderr'e, gider command1, command2, ...). Ekranda "normal" çıktı (komut dosyası woud olmadan çalıştırmak gibi set -x) ve bash "ekstra" çıktısı ayrı ayrı bir dosyada olması için mutlu olurdu .

Yani bunu ekranda yapmak istiyorum:

whatever output from command1
whatever output from command2

ve bu bir günlük dosyasında:

+ command1
+ command2

(ayrıca günlük dosyasında her şey varsa iyi olur)

set -x 2> fileO set komutunun çıktısı değil çünkü belli ki doens't, sağ etkili olması, ancak Bash davranışını değiştirmek.

bash 2> fileKomut dosyasının tamamını kullanmak da doğru şeyi yapmaz, çünkü bu kabukta çalışan her komutun stderr'ini yeniden yönlendirir, bu yüzden komutların hata mesajını görmüyorum.


2
Google-
Fu'm

Yanıtlar:


21

Bu ServerFault yanıtına dayanarak standart çıktıyı kesmeden bash -x çıktısını günlükBASH_XTRACEFD dosyasına gönder , modern bash sürümleri , çıktısı için alternatif bir dosya tanımlayıcı belirtmek için özel olarak içerirset -x

Yani örneğin

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

Aşağıdaki komutlar için normal standart çıktı ve standart hata akışlarını korurken çıktısını set -xdosyaya göndermek için logfile.

Fd 19 kullanımının keyfi olduğunu unutmayın - sadece kullanılabilir bir tanımlayıcı olması gerekir (yani 0, 1, 2 veya daha önce ayırdığınız başka bir sayı değil).


Gerçekten, bash izleme günlüğünü ayrı olarak kaydeder, ancak 2 çıkışı (ekrandaki stdout + stderr ve günlük dosyalarındaki bash izini) tamamen senkronize olmadıklarında okumak gerçekten zorlaşır. Az önce gönderdiğim çözüme bakın .
redseven

4

Bir yıldan fazla bir süre sonra ekranda hem "normal" çıktıya (stdout + stderr - bash trace) hem de bir dosyada (stdout + stderr + bash trace) sahip olmak için doğru çözümü buldum (bash.log) :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2

Bu sadece steeldriver cevabının ve bunun cevabının birleşimidir .
jarno

3

Steeldriver sana bir yaklaşım verdi . Alternatif olarak, STDERR dosyasını bir dosyaya yeniden yönlendirebilirsiniz:

script.sh 2> logfile

Ancak bu, hem set -xseçenek tarafından oluşturulan çıktının hem de üretilen diğer hata iletilerinin dosyaya gideceği anlamına gelir . Steeldriver'ın çözümü sadece set -xçıktıyı yönlendirir ki bu muhtemelen istediğiniz gibi olur.


“... hem set -x seçeneği tarafından oluşturulan çıktı hem de üretilen diğer hata mesajları dosyaya gidecek.” Bu yüzden benim için çalışmıyor. Benim asıl sorunum, kolayca "gerçek hataları" görmüyorum, çünkü tüm bu bash çıktı stderr gider. Komut hata mesajlarını yeniden yönlendirmek de bana "gerçek hataları" farklı bir şekilde gizleyecektir.
redseven

@redseven Korkarım ki istediğin şey çok net değil. Eğer Could düzenlemek soru ve netleştirmek? Stdout'a gitmeyecek herhangi bir şey için "çıktı" terimini kullanmaktan kaçının. İ) normal çıktıyı ayırmak istiyor musunuz? ii) komutunuz tarafından atılan hatalar ve iii) set -x? O zaman steeldriver'ın cevabı yeterli değil mi? Değilse, bize kopyalayabileceğimiz basit bir komut dosyasını gösterin ve nasıl davranmasını istediğinizi bize bildirin.
terdon

@steeldriver soruyu zaten mükemmel bir şekilde yanıtladı.
redseven

@ redseven ah, o zaman havalı. Yorumunuz çok sonra geldiğinden, hala bir şeye ihtiyacınız olduğunu düşündüm ve steeldriver'ın cevabının sorununuzu nasıl çözemediğini göremedim. Sevindim o zaman hepsi sıralandı.
terdon
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.