bash: "-x" yankısından ayrı satırlardan kaç


11

Bash'de, -xseçenekle çalışırken , tek tek komutların yankılanmasından muaf olması mümkün müdür?

Çıktıyı olabildiğince düzgün hale getirmeye çalışıyorum, bu yüzden komut dosyamın bazı bölümlerini bir alt kabukta çalıştırıyorum set +x. Bununla birlikte, satırın set +xkendisi hala yankılanır ve çıktıya değerli bir bilgi eklemez.

Kötü eski .batgünlerde hatırlıyorum , koşarken echo on, bireysel çizgiler a ile başlayarak muaf tutulabilir @. Bash'de eşdeğeri var mı?

#!/bin/bash -x

function i_know_what_this_does() {
  (
    set +x
    echo do stuff
  )
}

echo the next-next line still echoes 'set +x', is that avoidable?
i_know_what_this_does
echo and we are back and echoing is back on

Yukarıdakileri çalıştırırken, çıktı:

+ echo the next-next line still echoes 'set +x,' is that 'avoidable?'
the next-next line still echoes set +x, is that avoidable?
+ i_know_what_this_does
+ set +x
do stuff
+ echo and we are back and echoing is back on
and we are back and echoing is back on

Yanıtlar:


22

xtraceEğer yönlendirmek böylece çıkış, stderr'e gider stderriçin /dev/null:

i_know_what_this_does() {
  echo do stuff
} 2> /dev/null

Hala işlevlerin içinde çalışan komutlardan gelen hataları görmek istiyorsanız,

i_know_what_this_does() (
  { set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
)

Bu işlev için alt kabuk aracılığıyla yerel bir kapsam sağlamak (...)yerine , kullanımına dikkat edin {...}. bash, Sürüm 4.4 şimdi destekler beri local -Almquist kabukta gibi (benzer işleve yerel seçenekler yapmak set -o localoptionsiçinde zshsize yaparak altkabuk önlemek olabilir, böylece):

i_know_what_this_does() {
  { local -; set +x; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

bash4.0 ila 4.3 için bir alternatif , $BASH_XTRACEFDdeğişkeni kullanmak ve bunun için özel bir dosya tanımlayıcıya sahip olmaktır /dev/null:

exec 9> /dev/null
set -x
i_know_what_this_does() {
  { local BASH_XTRACEFD=9; } 2> /dev/null # silently disable xtrace
  echo do stuff
}

Yana basholan bir fd işaretlemek yeteneğinden mahrum yakın-on-exec olsa diğer komutlara o fd sızıntı yan etkisi yoktur bayrağı.

Ayrıca bu Bkz locvar.sh uygulamak için birkaç işlevlerini içeren yerel ile sağlamaktadır da POSIX komut değişkenleri ve işlevleri için kapsamı ve trace_fnve untrace_fnişlevleri onları yapmak XTrace d ya da değil.


Tatlı! Fonksiyonun kendisine uygulayabileceğim herhangi bir değiştirici olup olmadığını görmek istiyordum, ancak stderr'i yeniden yönlendirmeyi düşünmedim. Teşekkürler!
clacke

1
Btw, aynı sayfadan stchaz.free.fr/which_interpreter oldukça harika ve rahatsız edici. :-)
clacke

Ve şimdi buraya ikinci yöntem için tekrar geldim, set + x'i susturmadan yararlı stderr çıktısını susturmadan. Tekrar teşekkürler!
clacke

2

set +xYazdırılmasının nedeni, set -x"çalıştırmadan önce çalıştırmak üzere olduğunuz komutu, genişletmelerle, yazdırmadan önce yazdırmak. Bildiğim kadarıyla, bunun olmasını engellemenin bir yolu yok.


0

İşte aradığınız çözüm:

function xtrace() {
  # Print the line as if xtrace was turned on, using perl to filter out
  # the extra colon character and the following "set +x" line.
  (
    set -x
    # Colon is a no-op in bash, so nothing will execute.
    : "$@"
    set +x
  ) 2>&1 | perl -ne 's/^[+] :/+/ and print' 1>&2
  # Execute the original line unmolested
  "$@"
}

Orijinal komut bir kimlik dönüşümü altında aynı kabukta yürütülür. Çalıştırmadan hemen önce, argümanların yinelemesiz bir xtrace değerini alırsınız. Bu, stederr'i her "echo" komutunun kopyaları ile spam yapmadan önem verdiğiniz komutları xtrace yapmanızı sağlar.

# Example
echo "About to do something complicated ..."
xtrace do_something_complicated

Ya da kaçınmak perl(ve çok satırlı komutlarla ilgili sorunlar):+() { :;} 2> /dev/null; xtrace() { (PS4=; set -x; + "$@";{ set +x; } 2> /dev/null); "$@";}
Stéphane Chazelas

Hayır, üzgünüm, aradığım çözüm unix.stackexchange.com/a/60049/17980 . :-) set -xManevralar bana göre bir şey satın alıyor printf >&2 '+ %s\n' "$*"mu?
clacke

Olduğu gibi:xtrace() { printf >&2 '+ %s\n' "$*"; "$@"; }
clacke
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.