Ssh üzerinden bir komutun bitip bitmediğini nasıl bilebilirim?


1

Projem için dağıtım komut dosyaları yapıyorum ve hem yerel hem de uzaktan (ssh aracılığıyla bir sunucuda) komut çalıştırıp metin çıktısını döndürmesi gereken bir işlev yapıyorum.

Yerel bir komut çalıştırırken, komutun PID'sini bekleyerek bitip bitmediğini kolayca anlayabilirim. Açık bir SSH bağlantısı üzerinden bir komut gönderdiğimde çıktıyı geri alıyorum, ancak komutun çıkıp çıkmadığını veya komutun hala çalışıyor olup olmadığını ve daha sonra daha fazla çıkış üreteceğini bilmiyorum.

Şu anda bunu, her komut için sunucuya yeni bir bağlantı açarak çözdüm, söylemeye gerek yok ki çok yavaş .

Bu yaygın bir sorun olabilir gibi görünüyor ve basit bir çözümü olabilir, belki de SSH'ye yerleşik bir şey bile olabilir, bu yüzden burada soruyorum: Açık bir SSH bağlantısı üzerinden, komutları alıp almadığımı nasıl bilebilirim? gönderilenler bitti. Bir şekilde çıkış kodunu da toplayabilseydim çok iyi olurdu.


Daha somut bir örnek vermek gerekirse, bu temel olarak Ruby'deki sorunumu göstermektedir:

io = IO.popen(["ssh", "-q", "my-server"], "r+")

io.write("some command\n")

# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1

output = io.readpartial(1_000_000)

io.write("some command\n")

# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1

output = io.readpartial(1_000_000)

Bir betiği çalıştırmak ve yerel olarak çalıştırıldığı şekliyle uğraşmak ya da Mycommnad; InterestingPID=$? ; ... ;wait $InterestingPIDssh komutunun çok satırlı komutu olarak uzun bir komut vermek (buna benzer) ? BTW kullanabilirsiniz wait?
Hastur

@Hastur Korkarım ne demek istediğinizi anlamadım ...
Hubro

Üzgünüm, yeterince net değildim. Böyle bir şey yapmak istediğinizi , komutun PID'ini örneğin ( my_command -myoptions AndParameters) LetsStoreInterestingPID=$? komuttan hemen sonra ve bazı komutlardan sonra yakalamak istediğinizi hayal ediyorum wait $LetsStoreInterestingPID...
Hastur

Yanıtlar:


2

Komutunuzu bittiğinde size bildirecek bir komut dosyasına kaydırın.

Sunucunuzdan giden e-postaları kabul edecek bir SMTP sunucunuz varsa, bunu kullanabilirsiniz.

Aşağıdaki örnek, your-commandbir dosyaya çıktısını ve stderr dosyasını çalıştırır, sonra malixsonuçları postalamak için kullanır . Çıktının yakaladığı dosyanın $$takma değişkeni kullanmaktan farklı olduğundan emin olmanın kesinlikle çok daha iyi bir yolu var (belki rastgele bir dize üreten bir rutin kullanın).

#/bin/bash
your-command > /tmp/$$.$0.output 2>&1
RESULT=$?
echo >> /tmp/$$.$0.output
echo "Exit code $RESULT" >> /tmp/$$.$0.output
cat /tmp/$$.$0.output | mailx -s "your-command has finished with exit code $RESULT." you@some-mail-server.invalid
rm /tmp/$$.$0.output

Bir komut sırası belirtmenize izin veren bir şey istiyorsanız, bir sıradan komut eklemenizi ve silmenizi sağlayan Görev Biriktiricisi'ne ( apt-get install tspDebian'da) bakın ve bunların çıktısını size e-postayla gönderebileceğini düşünüyorum.

Sorunuzu daha dikkatli okuyun ... SSH bağlantısının neyi ham I / O akışı olarak girdiğini / çıkardığını ele alıyorsunuz .

SSH şifreli bir boru sağlar ve port iletimi için bazı özelliklere sahiptir, başka bir şey değildir. Bu boruya bağlanan tipik şey, genellikle diğer ucunda etkileşimli bir kullanıcı bekleyen bir kabuktur.

Ben düşünüyorum tek amaçlı tuşlar biraz sen biraz kolaylıkla yapmaya çalışıyorsun, ama kolay şey yapar küçük sarıcı komut dosyası oluşturmak için ne olacağını elde edebilirsiniz:

#/bin/bash
$@ 
echo "==== Command Output Finished ===="

ve sonra ==== Command Output Finished ====komut çıktıları arasındaki sınırın nerede olduğunu belirlemek için G / Ç yordamlarınızdaki dizeyi arayın . Elbette, bir komut için geçerli bir çıktının parçası olamayacak bir şey seçmelisiniz. Daha ayrıntılı bir şema mümkündür.

SMTP, sınır başlıkları ile benzer bir şey yapar.


Benim sorunum, find -type f -exec chmod 6640.001 saniye kadar süren hızlı komutları çalıştırıyorum . Böyle bir komut için bir SSH bağlantısı açtığımda, her biri birden fazla saniye sürüyor ve bu da dağıtım komut dosyasını yavaşlatıyor. SMTP sunucularını ve postalarını dahil etmek muhtemelen sorunu
çözmez

@Hubro Bu çözümü çalıştırmak ve kullanmak için komut listesi oluşturmanıza yardımcı olabilir mi? (birlikte olan cat list_of_command | ssh ...)
Hastur

Cevabımı güncelledim.
LawrenceC

Bu, yedekleme çözümüm olarak planladığım şeye benziyor. Rastgele bir SHA1 dizgesi üretip ; echo "$? c8m2js7a9..., sunucuya gönderdiğim her komutun ardından ekleyeceğimi ve komutun ne zaman biteceğini bilmek ve çıkış durumunu okumak için kullanacağımı düşündüm. Muhtemelen, normalde şeffaf bir şekilde uzaktaki sunucuda yürütülen komutları çalıştırmak gibi daha zarif bir çözüm olduğunu umuyordum.
Hubro

0

Her komutun ayrı bir SSH oturumunda çalıştırılması çözümünüzü sürdürürseniz, açık olan bir bağlantıyı kullanarak her oturuma başlamak için gereken süreyi hızlandırabilirsiniz. Bu, bağlantıyı sadece bir kez ek ödeme yapmanız gerektiği anlamına gelir, bu da takip eden oturumları hızlı bir şekilde başlatır.

Kurmanın en basit yolu, bununla ilk bağlantıyı açmaktır:

ssh -M -S /tmp/ssh_mux_%h_%p_%r myserver

Ardından her bağlantıyı aşağıdaki şekilde açın:

ssh -S /tmp/ssh_mux_%h_%p_%r myserver "command"

Daha bilgi yoktur ssh_configaltında man sayfasına ControlMasterve ControlPathveya çevrimiçi burada ve burada .

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.