문제

나는 실행하고 싶다 tail -f logfile Python의 Paramiko 모듈을 사용하여 원격 시스템에서 명령하십시오. 나는 지금까지 다음과 같은 방식으로 그것을 시도해 왔습니다.

interface = paramiko.SSHClient()
#snip the connection setup portion
stdin, stdout, stderr = interface.exec_command("tail -f logfile")
#snip into threaded loop
print stdout.readline()

필요에 따라 명령이 오래 실행되기를 원하지만 두 가지 문제가 있습니다.

  1. 이것을 깨끗하게 멈추는 방법은 무엇입니까? 나는 채널을 만들고 shutdown() 내가 그것을 통과 할 때 채널에 명령을 내리십시오. 그러나 그것은 지저분 해 보입니다. 보낸 것과 같은 일을 할 수 있습니까? Ctrl-C 채널의 Stdin에?
  2. readline() 블록, 그리고 출력을 얻지 못하는 블로킹 방법이 있으면 스레드를 피할 수 있습니까?
도움이 되었습니까?

해결책

1) 원하는 경우 고객을 닫을 수 있습니다. 다른 쪽 끝에있는 서버는 꼬리 프로세스를 죽입니다.

2) 블로킹하지 않는 방식 으로이 작업을 수행 해야하는 경우 채널 객체를 직접 사용해야합니다. 그런 다음 Channel.recv_ready () 및 Channel.recv_stderr_ready ()로 stdout과 stderr를 모두 시청하거나 select.select를 사용하십시오.

다른 팁

클라이언트에서 exec_command를 호출하는 대신 전송을 유지하고 자신의 채널을 생성하십시오. 그만큼 채널 명령을 실행하는 데 사용할 수 있으며 선택 문서에서 사용하여 데이터를 읽을 수있는시기를 찾을 수 있습니다.

#!/usr/bin/env python
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
  rl, wl, xl = select.select([channel],[],[],0.0)
  if len(rl) > 0:
      # Must be stdout
      print channel.recv(1024)

채널 객체는 원격 명령의 stdout 및 stdin과 연결하여 읽고 쓸 수 있습니다. 당신은 전화를 통해 Stderr에 갈 수 있습니다 channel.makefile_stderr(...).

타임 아웃을 설정했습니다 0.0 비 블로킹 솔루션이 요청 되었기 때문에 초. 필요에 따라 0이 아닌 타임 아웃으로 차단할 수 있습니다.

Andrew Aylett의 솔루션에 대한 작은 업데이트. 다음 코드는 실제로 루프를 중단하고 외부 프로세스가 완료되면 다음과 같습니다.

import paramiko
import select

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
channel = client.get_transport().open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
    if channel.exit_status_ready():
        break
    rl, wl, xl = select.select([channel], [], [], 0.0)
    if len(rl) > 0:
        print channel.recv(1024)

프로세스를 닫으려면 단순히 실행됩니다.

interface.close()

비 차단 측면에서는 차단을 읽지 못할 수 없습니다. 당신이 할 수있는 최선의 방법은 한 번에 하나의 "블록"을 구문 분석하는 것입니다. "stdout.read (1)"은 버퍼에 캐릭터가없는 경우에만 차단됩니다.

정보를 얻으려면 Channel.get_pty ()를 사용하여이를 수행하는 솔루션이 있습니다. 더 자세한 내용은 다음을 살펴 봅니다. https://stackoverflow.com/a/11190727/1480181

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top