Ssh'nin hedef makinede arka planda bir komut yürütmesi


304

Bu, ssh'yi bir kabuk betiğinde nasıl kullanıyorsunuz? soru. Uzak makinede o makinede arka planda çalışan bir komut yürütmek istersem, ssh komutunun geri dönmesini nasıl sağlayabilirim? Komutun sonuna "ve" işaretini (&) dahil etmeye çalıştığımda, kilitleniyor. Komutun tam şekli şöyle görünür:

ssh user@target "cd /some/directory; program-to-execute &"

Herhangi bir fikir? Unutulmaması gereken bir şey, hedef makineye girişlerin her zaman bir metin başlığı üretmesi ve SSH anahtarlarımın olması gerektiğinden şifre gerekmez.

Yanıtlar:


315

Bu problemi bir yıl önce yazdığım bir programda yaşadım - cevap oldukça karmaşık. Size kolaylık sağlamak için burada kopyalanan nohup üzerindeki wikipedia artcle'da açıklandığı gibi nohup kullanmanız ve çıkış yönlendirmesini kullanmanız gerekir .

Arka plandaki işleri yok saymak, örneğin SSH yoluyla oturum açarken yararlıdır, çünkü arka plandaki işler kabuğun bir yarış durumu nedeniyle oturumu kapatmasına neden olabilir [2]. Bu sorun, üç G / Ç akışının tümünü yeniden yönlendirerek de aşılabilir:

nohup myprogram > foo.out 2> foo.err < /dev/null &

1
Bu dosyalar geçerli dizinde oluşturulur. Dolayısıyla sınır, bölümdeki boş alan miktarıdır. Elbette yönlendirebilirsiniz /dev/null.
Frank Kusters

2
Bilgi istemi tamamlandıktan sonra sürecin arka planına dair herhangi bir fikir var mı? (şifre isteyen bitmiş bir gpg
isaaclw

Nohup kullanarak arka planda bir resque işçi başlatmaya çalışıyor, ama işe yaramaz .. :(
Infant Dev

1
Ne < /dev/nullanlama geldiğini açıklar mısınız? Teşekkürler.
Qian Chen

1
Ayrıca nohup ile ilgili wikipedia makalesinden: "Ayrıca, kapatılan bir SSH oturumunun bağlı işlemlere her zaman bir HUP sinyali göndermediğini unutmayın. Diğerlerinin yanı sıra, sözde bir terminalin tahsis edilip edilmediğine de bağlıdır." Yani kesinlikle nohup her zaman gerekli olmayabilirken, onunla uzun vadeden daha iyidir.
Jax

254

Benim için bunu yapmanın en temiz yolu: -

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

Bundan sonra çalışan tek şey uzak makinedeki gerçek komuttur


7
-n-fima edildiği gibi gerekli değildir-n
blissini

6
ssh -fssh işlemi bağlı, sadece arka plan bırakır. / Dev / null çözümleri ssh'nin hızlı bir şekilde bağlantısının kesilmesine izin verir, bu da tercih edilebilir.
Beni Cherniavsky-Paskin

Bu çözüm aynı zamanda bir Syonology NAS'a ssh üzerinden komut göndermek için de çalışır
Stefan F

Benim uzaktan göstermek için "ls -l" sonuçlarına ihtiyacım var, bu komut bunu yapmaz.
Siddharth

@Siddharth Ardından / dev / null yerine adlandırılmış bir dosyaya yönlendirin.
sherrellbc

29

Yönlendirmeler fd's

Çıktının, &>/dev/nullhem stderr hem de stdout'u / dev / null'a yönlendirdiği ve >/dev/null 2>/dev/nullveya ile eşanlamlı olduğu yeniden yönlendirilmesi gerekir >/dev/null 2>&1.

parantezlerin

En iyi yol, sh -c '( ( command ) & )'komutun herhangi bir şey olduğu yerde kullanmaktır .

ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Nohup Kabuğu

Kabuğu başlatmak için doğrudan nohup'ı da kullanabilirsiniz:

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Güzel Lansman

Başka bir hile, komutu / kabuğu başlatmak için nice kullanmaktır:

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

8
Bunun çok eski bir cevabınız olduğunu biliyorum, ancak parantezin neden en iyi yol olduğunu, (eğer varsa) fark eklemenin nohupne yaptığını ve neden ve ne zaman kullanacağınız hakkında bazı yorumlar ekleyebilir misiniz nice? Bu cevaba çok şey katacağını düşünüyorum.
Dr K

Belki buna kısmen cevap vermek için: Nohup ile, çalıştırılacak komuta & eklemeniz gerekmez.
Cadoiz

21

Bağlantıyı açık tutamazsanız / koruyamazsanız, ekranı kurma haklarına sahipseniz ekranı kullanabilirsiniz .

user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &

Ekran oturumunu ayırmak için: ctrl-a d

Ekran oturumlarını listelemek için:

screen -ls

Bir oturumu yeniden bağlamak için:

screen -d -r remote-command

Ekranın her oturumda birden çok kabuk oluşturabileceğini unutmayın. Benzer bir etki tmux ile elde edilebilir .

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &

Tmux oturumunu ayırmak için: ctrl-b d

Ekran oturumlarını listelemek için:

tmux list-sessions

Bir oturumu yeniden bağlamak için:

tmux attach <session number>

Varsayılan tmux kontrol anahtarını kullanmak ' ctrl-b', biraz zordur, ancak deneyebileceğiniz tmux ile birlikte gelen birkaç örnek tmux yapılandırması vardır.


3
bunun screeniçin nasıl kullanılır ?
Quamis

18

Sadece kesip yapıştırabileceğiniz çalışan bir örnek göstermek istedim:

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""

Çok yararlı. Teşekkürler.
Michael Martinez

8

En hızlı ve en kolay yol 'at' komutunu kullanmaktır:

ssh kullanıcı @ hedefi "şu an -f /home/foo.sh"


2
atYalnızca dosyadan değil, zaman geçtikten sonra kabul edilen komut satırı bağımsız değişkenleri için de bu genel bir çözüm olabilir .
Tyler Collier

3
<<< ile bir dosyayı şu şekilde simüle edebilirsiniz: ssh user @ target "şu anda -f <<< 'my_comnads'"
Nico

6

Bence istediğini elde etmek için bu cevaplardan birkaçını birleştirmen gerekecek. Noktalı virgülle birlikte nohup kullanırsanız ve her şeyi tırnak işaretleri içine alırsanız, şunları elde edersiniz:

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

bu benim için çalışıyor gibi görünüyor. Nohup ile çalıştırılacak komuta & işaretini eklemenize gerek yoktur. Ayrıca, komutun çıktılarından herhangi birini okumanız gerekmiyorsa,

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

tüm çıktıları / dev / null'a yönlendirmek için.


5

Bu benim için çalıştı kez:

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 

2

Böyle yapabilirsin ...

sudo /home/script.sh -opt1 > /tmp/script.out &

Mükemmel, PuTTY SSH oturumu ile çalışır. Çıkabilirim ve senaryo makinede devam eder. Teşekkür ederim.
Satria

1

Aslında, karmaşık olan uzak bir makinede bir komut çalıştırmam gerektiğinde, komutu hedef makinedeki bir komut dosyasına yerleştirmeyi ve ssh kullanarak bu komut dosyasını çalıştırmayı seviyorum.

Örneğin:

# simple_script.sh (located on remote server)

#!/bin/bash

cat /var/log/messages | grep <some value> | awk -F " " '{print $8}'

Ve sonra bu komutu kaynak makinede çalıştırıyorum:

ssh user@ip "/path/to/simple_script.sh"

0

Ben de aynı şeyi yapmaya çalışıyordum ama bunu Java'dan yapmaya çalıştığım ek karmaşıklık ile. Java çalıştıran bir makinede, arka planda (nohup ile) başka bir makinede bir komut dosyası çalıştırmaya çalışıyordum.

Komut satırından, işe yarayan şudur: (ana bilgisayara ssh için ihtiyacınız yoksa "-i keyFile" dosyasına ihtiyacınız olmayabilir)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

Benim komut satırına, "-c" sonra tüm tırnak içinde bir bağımsız değişken olduğunu unutmayın. Ama diğer tarafta çalışması için, hala tırnaklara ihtiyacı var, bu yüzden içine kaçan tırnaklar koymak zorunda kaldım.

Java'dan işe yarayan şudur:

ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
 "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.

Bu işe almak için biraz deneme yanılma aldı, ama şimdi iyi çalışıyor gibi görünüyor.


0

Benim gibi sözdizimini kullanarak uzak bir tmux oturumu yapmak benim için oldukça uygun görünüyordu tmux new -d <shell cmd>:

ssh someone@elsewhere 'tmux new -d sleep 600'

Bu, elsewhereana bilgisayarda yeni oturum başlatacak ve yerel makinedeki ssh komutu neredeyse anında kabuğa dönecektir. Daha sonra uzak ana bilgisayara ve tmux attacho oturuma ssh yapabilirsiniz . Yerel tmux koşusu hakkında hiçbir şey olmadığını, sadece uzak olduğunu unutmayın!

Ayrıca, işiniz bittikten sonra oturumunuzun devam etmesini istiyorsanız, komutunuzdan sonra bir kabuk başlatıcısı ekleyin, ancak tırnak işaretleri içine almayı unutmayın:

ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'

0
YOUR-COMMAND &> YOUR-LOG.log &    

Bu, komutu çalıştırmalı ve gerçekleşen sonuçları görmek için -F YOUR-LOG.log dosyasına kuyruk atabileceğiniz bir işlem kimliği atamalıdır. istediğiniz zaman çıkış yapabilirsiniz ve işlem devam edecektir


0

Bunu nohup olmadan yapabilirsiniz:

ssh user@host 'myprogram >out.log 2>err.log &'

-2

Sanırım ihtiyacınız olan şey bu: İlk önce sshpassmakinenize kurmanız gerekiyor . o zaman kendi betiğinizi yazabilirsiniz:

while read pass port user ip; do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
    COMMAND 1
    .
    .
    .
    COMMAND n
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP
      .      .       .       .
      .      .       .       .
      .      .       .       .
    PASS    PORT    USER    IP    
____HERE

-3

İlk önce bu prosedürü takip edin:

A'da kullanıcı a olarak oturum açın ve bir çift kimlik doğrulama anahtarı oluşturun. Bir parola girmeyin:

a@A:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa): 
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A

Şimdi B'de ~ b kullanıcısı olarak ~ / .ssh dizini oluşturmak için ssh komutunu kullanın. (Dizin zaten mevcut olabilir, ki bu iyidir):

a@A:~> ssh b@B mkdir -p .ssh
b@B's password: 

Son olarak a'nın yeni ortak anahtarını b @ B: .ssh / yetkili_anahtarlara ekleyin ve son kez b'nin şifresini girin:

a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password: 

Şu andan itibaren B'ye A'dan b olarak şifre olmadan giriş yapabilirsiniz:

a@A:~> ssh b@B

bu bir şifre girmeden çalışacaktır

ssh b @ B "cd / bazı / dizin; çalıştırılacak program &"


1
Soru, dagorym'in anahtarları bir şifre gerektirmeyecek şekilde ayarladığını söylüyor, ancak hala asılı
Max Nanasy
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.