로그 파일을 꼬집어 쓰려고합니다. 작동합니다. 그러나 나는 또한 출력을 분석하고 오류 등을 기록 할 수 있어야합니다. Paramiko-expect github 페이지에서 기본 예제를 사용하고 있으며이를 수행하는 방법을 알 수 없습니다. 이것은 그것의 지점으로 작동Paramiko Expect - Tailing
import traceback
import paramiko
from paramikoe import SSHClientInteraction
def main():
# Set login credentials and the server prompt
hostname = 'server'
username = 'username'
password = 'xxxxxxxx'
port = 22
# Use SSH client to login
try:
# Create a new SSH client object
client = paramiko.SSHClient()
# Set SSH key parameters to auto accept unknown hosts
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Connect to the host
client.connect(hostname, port, username, password)
# Create a client interaction class which will interact with the host
interact = SSHClientInteraction(client, timeout=10, display=False)
# Send the tail command
interact.send('tail -f /var/log/log')
# Now let the class tail the file for us
interact.tail(line_prefix=hostname+': ')
except KeyboardInterrupt:
print 'Ctrl+C interruption detected, stopping tail'
except Exception:
traceback.print_exc()
finally:
try:
client.close()
except:
pass
if __name__ == '__main__':
main()
은 로그가에서 실행되는 콘솔에 시간을 살고 인쇄,하지만 난 방식 paramiko에서 나는 OUPUT을 반복 할 수있는 방법을 알아낼 수 없습니다 기대 가치를 찾으십니까?
도움 말?
https://github.com/fgimian/paramiko-expect
이것은 또한 이벤트의 기록 백업을 위해 로컬 파일에 로그의 출력을 밀어 수있는 도움이 될 것이다.
업데이트 : 그래서이 정보가 표시되는 방식은 sys.stdout
입니다. 인터럽트 방식으로 출력을 끌어내는 방법이나이 방식을 여전히 작동 할 수있는 다른 유형의 출력으로 수정하는 방법에 익숙하지 않습니다. 나는 많은 성공없이이 모듈의 제작자에게 이메일을 보내려고 노력했다.
이 모듈은 매우 강력한 도구입니다. 실제로 출력을 모니터링 할 수 있다면 모듈을 매우 훌륭한 도구로 만들 수 있습니다. 도와주세요! Paramiko이-기대의
출력 섹션 : 꼬리 기능 :
# Read the output one byte at a time so we can detect \n correctly
buffer = self.channel.recv(1)
# If we have an empty buffer, then the SSH session has been closed
if len(buffer) == 0:
break
# Strip all ugly \r (Ctrl-M making) characters from the current
# read
buffer = buffer.replace('\r', '')
# Add the currently read buffer to the current line output
current_line += buffer
# Display the last read line in realtime when we reach a \n
# character
if current_line.endswith('\n'):
if line_counter and line_prefix:
sys.stdout.write(line_prefix)
if line_counter:
sys.stdout.write(current_line)
sys.stdout.flush()
line_counter += 1
current_line = ''
Paramiko가 기대 모듈 :
#
# Paramiko Expect
#
# Written by Fotis Gimian
# http://github.com/fgimian
#
# This library works with a Paramiko SSH channel to provide native SSH
# expect-like handling for servers. The library may be used to interact
# with commands like 'configure' or Cisco IOS devices or with interactive
# Unix scripts or commands.
#
# You must have Paramiko installed in order to use this library.
#
import sys
import re
import socket
# Windows does not have termios
try:
import termios
import tty
has_termios = True
except ImportError:
import threading
has_termios = False
import select
class SSHClientInteraction:
"""This class allows an expect-like interface to Paramiko which allows
coders to interact with applications and the shell of the connected
device.
"""
def __init__(self, client, timeout=60, newline='\r', buffer_size=1024,
display=False):
"""The constructor for our SSHClientInteraction class.
Arguments:
client -- A Paramiko SSHClient object
Keyword arguments:
timeout -- THe connection timeout in seconds
newline -- The newline character to send after each command
buffer_size -- The amount of data (in bytes) that will be read at a
time after a command is run
display -- Whether or not the output should be displayed in real-time
as it is being performed (especially useful when debugging)
"""
self.channel = client.invoke_shell()
self.newline = newline
self.buffer_size = buffer_size
self.display = display
self.timeout = timeout
self.current_output = ''
self.current_output_clean = ''
self.current_send_string = ''
self.last_match = ''
def __del__(self):
"""The destructor for our SSHClientInteraction class."""
self.close()
def close(self):
"""Attempts to close the channel for clean completion."""
try:
self.channel.close()
except:
pass
def expect(self, re_strings=''):
"""This function takes in a regular expression (or regular expressions)
that represent the last line of output from the server. The function
waits for one or more of the terms to be matched. The regexes are
matched using expression \n<regex>$ so you'll need to provide an
easygoing regex such as '.*server.*' if you wish to have a fuzzy match.
Keyword arguments:
re_strings -- Either a regex string or list of regex strings that
we should expect. If this is not specified, then
EOF is expected (i.e. the shell is completely closed
after the exit command is issued)
Returns:
- EOF: Returns -1
- Regex String: When matched, returns 0
- List of Regex Strings: Returns the index of the matched string as
an integer
"""
# Set the channel timeout
self.channel.settimeout(self.timeout)
# Create an empty output buffer
self.current_output = ''
# This function needs all regular expressions to be in the form of a
# list, so if the user provided a string, let's convert it to a 1
# item list.
if len(re_strings) != 0 and isinstance(re_strings, str):
re_strings = [re_strings]
# Loop until one of the expressions is matched or loop forever if
# nothing is expected (usually used for exit)
while (
len(re_strings) == 0 or
not [re_string
for re_string in re_strings
if re.match('.*\n' + re_string + '$',
self.current_output, re.DOTALL)]
):
# Read some of the output
buffer = self.channel.recv(self.buffer_size)
# If we have an empty buffer, then the SSH session has been closed
if len(buffer) == 0:
break
# Strip all ugly \r (Ctrl-M making) characters from the current
# read
buffer = buffer.replace('\r', '')
# Display the current buffer in realtime if requested to do so
# (good for debugging purposes)
if self.display:
sys.stdout.write(buffer)
sys.stdout.flush()
# Add the currently read buffer to the output
self.current_output += buffer
# Grab the first pattern that was matched
if len(re_strings) != 0:
found_pattern = [(re_index, re_string)
for re_index, re_string in enumerate(re_strings)
if re.match('.*\n' + re_string + '$',
self.current_output, re.DOTALL)]
self.current_output_clean = self.current_output
# Clean the output up by removing the sent command
if len(self.current_send_string) != 0:
self.current_output_clean = (
self.current_output_clean.replace(
self.current_send_string + '\n', ''))
# Reset the current send string to ensure that multiple expect calls
# don't result in bad output cleaning
self.current_send_string = ''
# Clean the output up by removing the expect output from the end if
# requested and save the details of the matched pattern
if len(re_strings) != 0:
self.current_output_clean = (
re.sub(found_pattern[0][1] + '$', '',
self.current_output_clean))
self.last_match = found_pattern[0][1]
return found_pattern[0][0]
else:
# We would socket timeout before getting here, but for good
# measure, let's send back a -1
return -1
def send(self, send_string):
"""Saves and sends the send string provided"""
self.current_send_string = send_string
self.channel.send(send_string + self.newline)
def tail(self, line_prefix=None):
"""This function takes control of an SSH channel and displays line
by line of output as \n is recieved. This function is specifically
made for tail-like commands.
Keyword arguments:
line_prefix -- Text to append to the left of each line of output.
This is especially useful if you are using my
MultiSSH class to run tail commands over multiple
servers.
"""
# Set the channel timeout to the maximum integer the server allows,
# setting this to None breaks the KeyboardInterrupt exception and
# won't allow us to Ctrl+C out of teh script
self.channel.settimeout(sys.maxint)
# Create an empty line buffer and a line counter
current_line = ''
line_counter = 0
# Loop forever, Ctrl+C (KeyboardInterrupt) is used to break the tail
while True:
# Read the output one byte at a time so we can detect \n correctly
buffer = self.channel.recv(1)
# If we have an empty buffer, then the SSH session has been closed
if len(buffer) == 0:
break
# Strip all ugly \r (Ctrl-M making) characters from the current
# read
buffer = buffer.replace('\r', '')
# Add the currently read buffer to the current line output
current_line += buffer
# Display the last read line in realtime when we reach a \n
# character
if current_line.endswith('\n'):
if line_counter and line_prefix:
sys.stdout.write(line_prefix)
if line_counter:
sys.stdout.write(current_line)
sys.stdout.flush()
line_counter += 1
current_line = ''
def take_control(self):
"""This function is a better documented and touched up version of the
posix_shell function found in the interactive.py demo script that
ships with Paramiko"""
if has_termios:
# Get attributes of the shell you were in before going to the
# new one
original_tty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
# We must set the timeout to 0 so that we can bypass times when
# there is no available text to receive
self.channel.settimeout(0)
# Loop forever until the user exits (i.e. read buffer is empty)
while True:
select_read, select_write, select_exception = (
select.select([self.channel, sys.stdin], [], []))
# Read any output from the terminal and print it to the
# screen. With timeout set to 0, we just can ignore times
# when there's nothing to receive.
if self.channel in select_read:
try:
buffer = self.channel.recv(self.buffer_size)
if len(buffer) == 0:
break
sys.stdout.write(buffer)
sys.stdout.flush()
except socket.timeout:
pass
# Send any keyboard input to the terminal one byte at a
# time
if sys.stdin in select_read:
buffer = sys.stdin.read(1)
if len(buffer) == 0:
break
self.channel.send(buffer)
finally:
# Restore the attributes of the shell you were in
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, original_tty)
else:
def writeall(sock):
while True:
buffer = sock.recv(self.buffer_size)
if len(buffer) == 0:
break
sys.stdout.write(buffer)
sys.stdout.flush()
writer = threading.Thread(target=writeall, args=(self.channel,))
writer.start()
try:
while True:
buffer = sys.stdin.read(1)
if len(buffer) == 0:
break
self.channel.send(buffer)
# User has hit Ctrl+Z or F6
except EOFError:
pass
왜 그냥'로컬 호스트에'는/var/log/log'을 scp'ing 여기를 분석 반복 : 여기
은 예입니다? 'diffutils'를 사용하여 새로운 파트를 찾을 수 있습니다. –