Timsahlarda boynunuza kalktığınızda, amacın bataklığı boşaltmak olduğunu unutmak kolaydır.
- popüler söyleyerek
Sorun şu an hakkında echo
ve henüz cevapların çoğunluğu bir set +x
komutu nasıl gizlice sokacağımıza odaklandı . Çok daha basit ve daha doğrudan bir çözüm var:
{ echo "Message"; } 2> /dev/null
(Daha { …; } 2> /dev/null
önceki cevaplarda görmemiş olup olmadığımı düşünmemiş olabileceğimi kabul ediyorum .)
Bu biraz hantaldır, ancak ardışık echo
komutlar bloğunuz varsa , bunu her biri için ayrı ayrı yapmanız gerekmez:
{
echo "The quick brown fox"
echo "jumps over the lazy dog."
} 2> /dev/null
Yeni çizgileriniz olduğunda noktalı virgül kullanmanıza gerek olmadığını unutmayın.
Sen kullanarak yazarak yükünü azaltabilir kenorb fikrini
açma /dev/null
standart olmayan bir dosya tanımlayıcı üzerinde kalıcı (örneğin 3) ve daha sonra söyleyerek 2>&3
yerine 2> /dev/null
her zaman.
Bu yazının yazıldığı anda ilk dört cevaplar (çoğu durumda, hantal içinde ve) özel bir şey yapıyor gerektiren
her bir yapmak zaman echo
. Eğer gerçekten tüm echo
komutların yürütme izini bastırmasını istiyorsanız (ve neden olmasın?), Çok fazla kod sarsmadan bunu global olarak yapabilirsiniz. İlk olarak, takma adların izlenemediğini fark ettim:
$ myfunc()
> {
> date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016 0:00:00 AM # Happy Halloween!
$ myfunc
+ myfunc # Note that function call is traced.
+ date
Mon, Oct 31, 2016 0:00:01 AM
$ myalias
+ date # Note that it doesn’t say + myalias
Mon, Oct 31, 2016 0:00:02 AM
(Shebang, bash bağlantısı #!/bin/sh
olsa bile , aşağıdaki betiğin snippet'lerinin işe yaradığını unutmayın /bin/sh
. Ancak, eğer shebang ise #!/bin/bash
, shopt -s expand_aliases
takma adın bir komut dosyasında çalışmasını sağlamak için bir komut eklemeniz gerekir .)
Yani ilk numaram için:
alias echo='{ set +x; } 2> /dev/null; builtin echo'
Şimdi, söylediğimizde echo "Message"
takma ismini arıyoruz, ki bu izlenmiyor. Diğer ad, izleme mesajını set
komuttan gizleyerek ( önce user5071535'in cevabında sunulan tekniği kullanarak ) izlemeyi kapatır ve sonra gerçek echo
komutu çalıştırır . Bu, her echo
komutta kodu düzenlemeye gerek kalmadan kullanıcı5071535'in cevabına benzer bir etki elde etmemizi sağlar . Ancak, bu izleme modunu kapalı bırakır. Bir set -x
takma adı koyamayız (veya en azından kolayca değil) çünkü takma ad yalnızca bir dize bir sözcüğün yerine kullanılmasına izin verir; takma ismin dizisinin hiçbir kısmı argümanlardan sonra komuta enjekte edilemez
(örn "Message"
.). Örneğin, komut dosyası içeriyorsa
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date
çıktı
+ date
Mon, Oct 31, 2016 0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016 0:00:04 AM # Note that it doesn’t say + date
bu nedenle, ileti (ler) i görüntüledikten sonra izleme seçeneğini tekrar açmanız gerekir - ancak ardışık her komut bloğundan sonra yalnızca bir kez echo
:
date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date
Biraz set -x
sonra echo
hile yaparak otomatikleştirmeyi başarırsak iyi olurdu . Fakat bunu sunmadan önce bunu düşünün. OP, bir #!/bin/sh -ex
shebang kullanan senaryolarla başlıyor . Örtülü olarak kullanıcı kullanıcıyı x
shebang'dan kaldırabilir ve yürütme izlemesi olmadan normal şekilde çalışan bir komut dosyasına sahip olabilir. Bu özelliği koruyan bir çözüm geliştirebilseydik daha iyi olurdu. Buradaki ilk birkaç cevap, bu özellikten başarısız oldu çünkü echo
zaten açık olup olmadığına bakılmaksızın koşulsuz olarak ifadelerden sonra “geriye” doğru izlemeye başladılar .
Bu cevap dikkat çekici bir şekilde bu konuyu değiştirmekte başarısız oluyor echo
iz çıkışı ile çıktı; bu nedenle, izleme kapatıldığında tüm mesajlar kaybolur. Şimdi koşullu bir echo
ifadeden sonra geriye dönüş yapan bir çözüm sunacağım - sadece açıksa. Bunu koşulsuz olarak “geri” izleyen bir çözüme indirgemek önemsizdir ve bir egzersiz olarak bırakılır.
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
builtin echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
$-
seçenekler listesi; ayarlanan tüm seçeneklere karşılık gelen harflerin birleştirilmesi. Örneğin, e
ve x
seçenekleri ayarlanmışsa, o $-
zaman e
ve içeren harflerin bir kargaşası olacaktır x
. Yeni takma adım (üstte) $-
izlemeyi kapatmadan önce değerini korur. Ardından, izleme kapalıyken kontrolü bir kabuk fonksiyonuna atar. Bu işlev gerçek olanı yapar ve diğer ad çağrıldığında seçeneğin açık echo
olup olmadığını kontrol eder x
. Seçenek açıksa, işlev tekrar açar; kapalıysa, işlev onu bırakır.
shopt
Senaryonun başına yukarıdaki yedi satırı (eğer varsa, sekiz) ekleyebilir ve gerisini yalnız bırakabilirsiniz.
Bu sana izin verecek
- Aşağıdaki shebang hatlarından herhangi birini kullanmak için:
#! / bin / sh -ex
#! / bin / sh -e
#! / bin / sh –x
ya da sadece düz#! / Bin / sh
ve beklendiği gibi çalışması gerekir.
- koduna sahip olmak
(shebang)
komut 1
komut 2
komut 3
-x ayarla
komut 4
komut 5
komut 6
+ x ayarla
komut 7
komut 8
komut 9
ve
- Komutlar 4, 5 ve 6 izlenecek - bunlardan biri bir değilse
echo
, bu durumda uygulanacak ancak izlenmeyecektir. (Ancak komut 5 bir olsa bile echo
, komut 6 hala izlenecektir.)
- Komutlar 7, 8 ve 9 izlenmeyecek. Komut 8 bir an olsa bile
echo
, komut 9 hala izlenmeyecektir.
- 1, 2 ve 3 komutları, Shebang'ın içerip içermediğine bağlı olarak izlenecek (4, 5 ve 6 gibi) veya olmayacak (7, 8 ve 9 gibi)
x
.
PS: Sistemimde, builtin
anahtar kelimeyi orta cevabımda (sadece takma ad için olan echo
) dışlayabileceğimi öğrendim . Bu şaşırtıcı değil; bash (1), takma ad genişletmesi sırasında…
… Genişletilen diğer adıyla aynı olan bir kelime ikinci kez genişletilmez. Bir takma adlı olabileceğini Bu araçlar ls
için ls -F
, örneğin, ve bash yinelemeli yedek metni genişletmek için çalışmaz.
Çok da şaşırtıcı olmayan bir şekilde, anahtar kelime 1 girilmezse , son cevap (cevap veren echo_and_restore
) başarısız olur . Ancak, silerek ve sırasını değiştirirseniz garip bir şekilde çalışır :builtin
builtin
echo_and_restore() {
echo "$*"
case "$save_flags" in
(*x*) set -x
esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
__________
1 Tanımlanmamış davranışa yol açıyor gibi görünüyor. gördüm
- sonsuz bir döngü (muhtemelen sınırlandırılmamış özyineleme nedeniyle),
- bir
/dev/null: Bad address
hata mesajı ve
- Bir çekirdek dökümü.
echo +x; echo "$*"; echo -x
bir takma adın eşdeğerini yapmanın bir yolunu sunabilirse , onu görmek isterim.