ssh si blocca quando il comando viene richiamato direttamente, ma esce in modo pulito quando viene eseguito in modo interattivo

StackOverflow https://stackoverflow.com/questions/33475

  •  09-06-2019
  •  | 
  •  

Domanda

Devo avviare un server sul computer remoto e recuperare il numero di porta su cui si sta installando il processo del server.Quando richiamato, il server ascolterà su una porta casuale e restituirà il numero di porta su stderr.

Desidero automatizzare il processo di accesso al computer remoto, avvio del processo e recupero del numero di porta.Ho scritto uno script Python chiamato "invokejob.py" che risiede sulla macchina remota per fungere da wrapper che richiama il lavoro e quindi restituisce il numero di porta, assomiglia a questo:

import re, subprocess
executable = ... # Name of executable
regex = ... # Regex to extract the port number from the output
p = subprocess.Popen(executable,
    bufsize=1, # line buffered
    stderr=subprocess.PIPE
    )
s = p.stderr.readline()
port = re.match(regex).groups()[0]
print port

Se accedo in modo interattivo, questo script funziona:

$ ssh remotehost.example.com
Last login: Thu Aug 28 17:31:18 2008 from localhost
$ ./invokejob.py
63409
$ exit
logout
Connection to remotehost.example.com closed.

(Nota:disconnessione riuscita, non si è bloccato).

Tuttavia, se provo a invocarlo dalla riga di comando, si blocca:

$ ssh remotehost.example.com invokejob.py

Qualcuno sa perché si blocca nel secondo caso e cosa posso fare per evitarlo?

Tieni presente che devo recuperare l'output del programma, quindi non posso semplicemente utilizzare il flag ssh "-f" o reindirizzare l'output standard.

È stato utile?

Soluzione

s = p.stderr.readline()

Sospetto che sia la riga sopra.Quando invochi un comando direttamente tramite ssh, non ottieni il tuo pty completo (supponendo Linux), e quindi nessuno stderr da cui leggere.

Quando accedi in modo interattivo, stdin, stdout e stderr sono impostati per te e quindi il tuo script funziona.

Altri suggerimenti

@Ben Collins

Penso che tu abbia ragione riguardo al fatto che stderr sia un problema.Sono abbastanza sicuro che si stia bloccando sulla chiamata readline().

Alla fine ho rinunciato e ho deciso di utilizzare il modulo pxssh di aspettativa per automatizzare la mia interazione con una sessione ssh.

@Misha M

Sfortunatamente, il trucco del punto e virgola non funziona qui:si blocca durante l'esecuzione del mio programma.

cosa succede se fai quanto segue:

ssh <remote host> '<your command> ;<your regexp using awk or something>'

Per esempio

ssh <remote host> '<your program>; ps aux | awk \'/root/ {print $2}\''

Questo si collegherà a , eseguirà e quindi stamperà ogni PSID per qualsiasi utente root o qualsiasi processo con root nella sua descrizione.

Ho utilizzato questo metodo per eseguire tutti i tipi di comandi su macchine remote.Il problema è racchiudere i comandi che si desidera eseguire tra virgolette singole (') e separare ciascun comando con un punto e virgola (;).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top