Eko gibi davranan ancak stdout'tan ziyade stderr'a çıktı veren standart bir Bash aracı var mı?
Yapabileceğimi biliyorum echo foo 1>&2ama biraz çirkin ve şüpheli, hata eğilimli (örneğin işler değiştiğinde yanlış düzenleme olasılığı daha yüksek).
Eko gibi davranan ancak stdout'tan ziyade stderr'a çıktı veren standart bir Bash aracı var mı?
Yapabileceğimi biliyorum echo foo 1>&2ama biraz çirkin ve şüpheli, hata eğilimli (örneğin işler değiştiğinde yanlış düzenleme olasılığı daha yüksek).
Yanıtlar:
Bunu, okumayı kolaylaştırarak yapabilirsiniz:
>&2 echo "error"
>&2# 2 dosya tanımlayıcısını 1 numaralı dosya tanımlayıcısına kopyalar. Bu nedenle, bu yeniden yönlendirme gerçekleştirildikten sonra, her iki dosya tanıtıcısı da aynı dosyaya başvurur: bir dosya tanıtıcısı # 2 başlangıçta atıfta bulundu. Daha fazla bilgi için Bash Hackerları Resimli Yeniden Yönlendirme Eğiticisine bakın .
aliasBir kabuk komut dosyasında bir kullanmak bilmiyorum . Muhtemelen kullanımı daha güvenli olurerrcho(){ >&2 echo $@; }
errcho(){ >&2 echo $@|pr -To5;}işe yaramaz. Böyle bir şey yapmak için, yönlendirmeyi son borudan sonra bir yere koymak zorunda kalacaksınız:errcho(){ echo $@|>&2 pr -To5;}
Bir işlev tanımlayabilirsiniz:
echoerr() { echo "$@" 1>&2; }
echoerr hello world
Bu bir komut dosyasından daha hızlı olacaktır ve bağımlılıkları olmayacaktır.
Camilo Martin'in bash özel önerisi bir "burada dize" kullanır ve yankının normalde yutacağı argümanlar (-n) da dahil olmak üzere ilettiğiniz her şeyi yazdırır:
echoerr() { cat <<< "$@" 1>&2; }
Glenn Jackman'ın çözümü aynı zamanda yutma problemini de önler:
echoerr() { printf "%s\n" "$*" >&2; }
echoerr -ne xt"-ne xt" yazdırmayacak. Bunun için daha iyi kullanın printf.
echoerr() { cat <<< "$@" 1>&2; }
printf "%s\n" "$*" >&2
$IFShalinde ayrı bir argüman olarak gönderilir boşluk echoile bitiştirmek araçlarla 0x20s, ancak tip 2 daha az karakterden oluşan çok outweight kolaylık alıntı değil tehlikeleri) .
Yana 1standart çıkışı, açıkça gibi bir çıkış yönlendirme önünde adlandırın gerekmez >ancak bunun yerine basitçe yazabilirsiniz:
echo Bu mesaj stderr> & 2'ye gider
1>&2Güvenilir bir şekilde yazmanızın zor olacağından endişe duyduğunuzdan , gereksizliğin ortadan kaldırılması sizin için 1hafif bir teşvik olabilir!
Başka seçenek
echo foo >>/dev/stderr
foo- örneğin - kendi Stderr yönlendirildi vardır foo >foo.log 2>&1- o zaman echo foo >/dev/stderrbundan önceki bütün çıktıyı pataklayacak. >>yerine kullanılmalıdır:echo foo >>/dev/stderr
/dev/fd/2.
/proc/self/fd/2. Aşağıdaki cevabımı gör :)
Hayır, bunu yapmanın standart yolu bu. Hatalara neden olmamalıdır.
1>&2. Hepimiz bunun gerçekleşmemesini dileriz, ancak eminim hepimiz olduğu yerler olmuştur.
( echo something 1>&2 ; something else ) > log-> (echo something; cp some junk 1>&2 ; something else) > logHata.
İletiyi syslog dosyasına da kaydetmeyi önemsemiyorsanız, not_so_ugly yolu:
logger -s $msg
-S seçeneği şu anlama gelir: "İletiyi standart hataya ve sistem günlüğüne gönder."
Bu, boru girişini STDERR'a yönlendiren basit bir STDERR işlevidir.
#!/bin/bash
# *************************************************************
# This function redirect the pipe input to STDERR.
#
# @param stream
# @return string
#
function STDERR () {
cat - 1>&2
}
# remove the directory /bubu
if rm /bubu 2>/dev/null; then
echo "Bubu is gone."
else
echo "Has anyone seen Bubu?" | STDERR
fi
# run the bubu.sh and redirect you output
tux@earth:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err
echo what | /dev/stderr...
Not: Ben post-cevap stderr çıktı yanıltıcı / belirsiz "yankı" değil soru (zaten OP tarafından cevaplandı).
Niyeti göstermek ve istediğiniz uygulamayı kaynaklamak için bir işlev kullanın . Örneğin
#!/bin/bash
[ -x error_handling ] && . error_handling
filename="foobar.txt"
config_error $filename "invalid value!"
output_xml_error "No such account"
debug_output "Skipping cache"
log_error "Timeout downloading archive"
notify_admin "Out of disk space!"
fatal "failed to open logger!"
Ve error_handlingolmak:
ADMIN_EMAIL=root@localhost
config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }
output_xml_error() { echo "<error>$*</error>" 2>&1; }
debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }
log_error() { logger -s "$*"; }
fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }
notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }
OP'deki endişeleri ele alan nedenler:
Diğer sebepler:
Benim önerim:
echo "my errz" >> /proc/self/fd/2
veya
echo "my errz" >> /dev/stderr
echo "my errz" > /proc/self/fd/2olacak etkili bir çıkış stderrnedeniyle /proc/selfcari sürecine bir bağlantıdır ve /proc/self/fdsüreç açılan dosya tanımlayıcıları tutan ve daha sonra 0, 1ve 2ayakta stdin, stdoutve stderrsırasıyla.
/proc/selfBağlantı MacOS çalışmıyor, ancak, /proc/self/fd/*Android'de Termux geçerli değil /dev/stderr. Bash betiğinden işletim sistemi nasıl algılanır? hangi varyantı kullanacağınızı belirleyerek komut dosyanızı daha taşınabilir hale getirmeniz gerekiyorsa yardımcı olabilir.
/proc/selfMacOS'ta çalışmıyor, bu yüzden daha basit bir /dev/stderryöntemle devam edeceğim . Ayrıca, diğer cevaplarda / yorumlarda belirtildiği gibi, >>eklemek için kullanmak daha iyidir .
/proc/self/fd/*Android'de Termux'da kullanılabilir, ancak mevcut değildir /dev/stderr.
catBurada bahsedildiği gibi kullanmayın . cata, programı
sırasında echove printf(kabuk) yerleşiklere deneme vardır. Bir programın veya başka bir komut dosyasının (yukarıda da belirtildiği gibi) başlatılması, tüm maliyetleri ile yeni bir süreç oluşturmak anlamına gelir. Yerleşikleri kullanarak yazma işlevleri oldukça ucuzdur, çünkü bir işlem (-evre) oluşturmaya (yürütmeye) gerek yoktur.
Opner "çıkışı (herhangi standart bir araç olduğunu sorar boru stderr)", schort cevap: HAYIR ... neden? ... rediredcting boruları bu kavramlar üzerine kurulmuş olan unix (Linux ...) ve bash (sh) gibi sistemlerde temel bir kavramdır.
Bunun gibi notasyonlarla yönlendirmenin açıcıya katılıyorum: &2>1modern programcılar için çok hoş değil, ama bu bash. Bash büyük ve sağlam programlar yazmak için tasarlanmamıştı, yöneticilerin daha az tuşa basmak için oraya ulaşmasına yardımcı olmak için tasarlandı ;-)
Ve en azından, yönlendirmeyi satırın herhangi bir yerine yerleştirebilirsiniz:
$ echo This message >&2 goes to stderr
This message goes to stderr
catbirisini birisine bildirmek ile birine kedi kullanmamalarını bildirmek arasında bir fark var, çünkü bu yavaş. Kedinin doğru seçim olduğu sayısız kullanım durumu vardır, bu yüzden cevabınıza itiraz ediyorum.
echodeğişiklik istedi . Kullansa bile cat, bir bash yönlendirmesi kullanması gerekir. neyse. Yani, burada kullanmak için hiçbir anlamı yoktur cat. BTW catGünde 100 kez kullanıyorum , ama asla açıcı istediğinde bağlamda ... anladınız mı?
Son zamanlarda tökezlediğim başka bir seçenek şudur:
{
echo "First error line"
echo "Second error line"
echo "Third error line"
} >&2
Bu, çok satırlı hata çıkışını daha az hataya eğilimli hale getirirken yalnızca Bash yerleşiklerini kullanır (çünkü &>2her satıra eklemeyi hatırlamanız gerekmez ).
catveya soru için konu dışı başka bir yardımcı programın kullanılmamasını tavsiye ediyor .
read stderr'e yazdırılan ve yeniden yönlendirme hileleri yapmadan yankı gibi kullanılabilen bir kabuk yerleşik komutudur:
read -t 0.1 -p "This will be sent to stderr"
Bu -t 0.1, bir stdin satırını bir değişkene depolayarak, okunan ana işlevselliğini devre dışı bırakan bir zaman aşımıdır.
Senaryo yap
#!/bin/sh
echo $* 1>&2
bu sizin aracınız olur.
Veya ayrı bir dosyada komut dosyası istemiyorsanız bir işlev yapın.
Mac OS X: Kabul edilen yanıtı ve birkaç diğer yanıtı denedim ve hepsi Mac'imde STDERR değil STDOUT yazdı.
Perl kullanarak standart hataya yazmanın taşınabilir bir yolu:
echo WARNING! | perl -ne 'print STDERR'