Tüm bash betiği işlemlerini tam olarak nasıl kaydederim?


44

Her iki hata iletisiyle birlikte TÜM günlük verilerini komut dosyası çıktımdan yakalamak ve hepsini günlük dosyasına yönlendirmek istiyorum.

Aşağıdaki gibi bir komut dosyası var:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Dosyadaki tüm işlemleri görmek istiyorum /home/scripts/cron/logs

Ama sadece yankı komutundan sonra koyduğum şeyi görüyorum.

Günlüklerde nasıl kontrol edilir SSH komutu başarılı oldu?

Tüm kayıt verilerini toplamam gerekiyor. Komut dosyamdaki her komutun sonucunu izlemek, komut dosyası başarısız olurken neler olduğunu daha iyi analiz etmek için buna ihtiyacım var.


Bunu yapmak için "script" de kullanabilirsiniz. Bu
gönderiye

errexit ile dikkatli olmalısınız - farkına varılmadığını ya da örneğin betişten çıkmadığını fark ettim. komut dosyasında böyle bir şey varsa: komut || komut başarısız olduğunda dosmthg komut dosyası errexit setiyle hemen çıkmaz ama sadece dosmthg komutunu çalıştırır ve komut dosyasını devam

Yanıtlar:


66

Genelde her betiğin başına aşağıdakine benzer bir şey koyarım (özellikle de bir arka plan programı olarak çalışırsa):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Açıklama:

  1. exec 3>&1 4>&2

    Dosya tanımlayıcılarını kaydeder, böylece yeniden yönlendirmeden önce ne olursa olsun geri yüklenir veya sonraki yönlendirmeden önce ne olursa olsun çıktı olarak kullanılırlar.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Belirli sinyaller için dosya tanımlayıcılarını geri yükleyin. Genel olarak gerekli değildir, çünkü alt kabuk çıktığında geri yüklenmeleri gerekir.

  3. exec 1>log.out 2>&1

    Redirect stdoutdosyaya log.outdaha sonra yeniden yönlendirmek stderriçin stdout. Aynı dosyaya gitmelerini istediğinizde, siparişin önemli olduğunu unutmayın. stdout gerekir önce yönlendirilecek stderryönlendirilir stdout.

O andan itibaren, konsoldaki çıktıyı görmek için (belki), sadece yönlendirebilirsiniz &3. Örneğin,

echo "$(date) : part 1 - start" >&3

stdoutYukarıdaki satır 3'ü uygulamadan önce muhtemelen konsola yönlendirildiği yere gidecektir .


<< niceroot, teşekkürler! Bu üç dizeyi (exec, trap, exec) betiğin başına ekledim ve hem stdout hem de stderr'ı alabiliyorum. Ancak Bir sorun: "Dosya tanımlayıcı 3'ü (yöneltme: XXX) some_command'da sızdırılmış" görmüştüm ... Lütfen bu hataları almaktan nasıl kaçınabileceğimi söyle. Özel tahtada busybox tabanlı sh kullanıyorum.
kumar

3
Burada Büyük KungFu !!! - Daha da iyisi kullanmaktır trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. RETURN sözde sigspec, bir kabuk işlevi veya. veya kaynak yerleşikleri çalıştırmayı tamamlar. Bunun için (ve diğer nedenlerden dolayı) senaryolarımda son 2 satır ekledim : return& exit 0- Sadece 2 sentim, size @ nicerobot!
DavAlPi

Küresel kabuk değişkenleri aracılığıyla kabuk komut dosyalarının günlüğe kaydedilmesinde çok fazla ayrıntı vardır. Benzer bir günlüğe kaydetmeyi kabuk komut dosyasında taklit edebiliriz: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html Yazının INFO, DEBUG, ERROR gibi günlük seviyelerinin tanıtılmasıyla ilgili ayrıntıları vardır. Komut dosyası girişi, komut dosyası çıkışı, işlev girişi, işlev çıkışı gibi ayrıntıları izleme.
Piyush Chordia

trapSinyallerin numaralandırılması biraz garip görünüyor. Genellikle dahil etmek isteyeceksiniz 15.
üçlü,


14

ssh çıktısını logfile nize almak için yönlendirmeniz stderrgerekir stdout. 2>&1bash betiğinizden sonra ekleyerek bunu yapabilirsiniz .

şöyle görünmeli:

#!/bin/bash
(
...
) 2>&1 | tee ...

bu, mesajları doğru sırada göstermediğinde, başka bir alt kabuk eklemeye çalış:

#!/bin/bash
((
...
) 2>&1) | tee ...

1
Bu harika çalışıyor. Aslında hem stdout'u hem de stderr'i şu yollarla yönlendirebilirsiniz:( ... ) |& tee output.log
Noam Manos

12

Sorunuzu okuduğumda çıktıyı kaydetmek istemezsiniz, ancak komutların tamamı, bu durumda, diğer cevaplar size yardımcı olmaz.

Her şeyi elde etmek için kabuk betiğini -x ile çağırın:

sh -x foo.sh

İstediğiniz dosyaya giriş yapın:

sh -x foo.sh >> /home/scripts/cron/logs


2
-X seçeneği için 1
Coc

10

Bash'da bunu koyabilirsiniz set -xve bundan sonra yürüttüğü her komutu (ve bash değişkenlerini) yazdıracaktır. İle kapatabilirsiniz set +x.

Eğer paranoyak olmak istiyorsan, set -o errexitsenaryoyu yazabilirsin. Bu, bir komut sıfır olmayan bir çıkış kodu döndürürse, komutun başarısız olacağı ve duracağı anlamına gelir; bu, bir şeylerin yanlış gittiğini işaret etmek için unix standart yoludur.

Eğer güzel günlükleri almak istiyorsanız, size bakmak gerekir tsyılında moreutilsdebian / ubuntu paketinin. Her satır bir zaman damgası ile ön ekler ve yazdırır. Böylece olayların ne zaman gerçekleştiğini görebilirsiniz.


1
"set -o errexit", "set -e" ile aynı şey olmalı
Ajith Antony,

0

Başkalarının söylediklerinin ardından, set el kitabı iyi bir kaynaktır. Koydum:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Senaryoların tepesinde, devam etmeyi sürdürmek isterim, yoksa set -exhata çıkması gerekiyorsa.


Bu, ssh loglarına ve komutların başarılı bir şekilde yürütülmesine nasıl yardımcı olur?
asktyagi

OP'nin kukla betiği ile test etmek, her komutu ve sonucu ne olursa olsun kaydeder: ssh zaman aşımı, hatalı etki alanı vb. Veya geçerli bir ssh adresi için komutları uzak kabuğa kaydeder. Belki de ssh girişleri hakkında daha fazla bilgi gerekiyorsa ssh -vv?
dragon951
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.