Python для системного администратора windows книга

Python for Systems Administrator. Contribute to tuladhar/Python-for-SysAdmin development by creating an account on GitHub.

Python3 for Systems Administrator

Contents

Getting Started Standard Input, Output and Error

Standard input, output and error (commonly referred to as stdin , stdout and stderr ) are what’s called pipes.

These pipes are normally connected to the terminal window where you are working.

When printing something (using print() ), it goes to the stdout pipe by default; when your program needs to print errors (like a traceback in Python), it goes to the stderr pipe; and when your program requires input from a user or other programs, it goes to the stdin pipe.

$ cat /etc/passwd | grep /bin/bash # `_ writes to stdout `_ reads from stdin $ ls no_such_file.txt # `_ writes to stderr

Python built-in sys module provides stdin , stdout and stderr as a file-objects, exposing read() , readlines() , write() , writelines() methods, as shown below:

#!/usr/bin/env python3 import sys # writing to stdout pipe print ('Hello, world') sys.stdout.write('Hello, worldn') # writing to stderr pipe print("Error occured") sys.stderr.write("Error occuredn") # reading single line from stdin pipe sys.stdout.write('Username: ') username = sys.stdin.readline() print (username) # reading 'n' number of characters from stdin print ('Enter few characters and press Ctrl-D') data = sys.stdin.read(1024) print('len(data):', len(data)) # reading lines (separated by newlines) from stdin print('Enter few lines and press Ctrl-D') lines = sys.stdin.readlines() print ('total lines read:', len(lines))

Getting Started Working with files

Python built-in open function is the standard interface for working with files. open returns a file object with familiar methods for performing read/write operations.

Common arguments:
  • file: absolute or relative path of the file. e.g: /etc/passwd , ./ip-list.txt
  • mode: an optional string specifying mode in which the file is opened. Default’s to r for reading in text mode. Common values are:
  • w write only (truncates the file already exists)
  • x create and write to a new file (if file already exists then open fails)
  • a append to a file (insert data to end of the file)
  • + updating a file (reading and writing). e.g: r+ w+
  • b binary mode for non-text files. Contents are returned as byte objects.
  • t text mode (default). Contents are returned as strings .
File object methods:
  • .close()
  • .read(size=-1) read at most n characters. If n is negative or ommited, reads the whole file until EOF .
  • .readline() Read single line until newline or EOF .
  • .readlines() Read all newlines and returns as a list.
  • .write(data) Write data to file. Returns number of characters written.
  • .writelines(list) Write all data in the list. Useful for writing multiple lines to a file.
Example
## Reading a file r = open('/etc/passwd') # same as: # r = open('/etc/passwd', 'r') passwd = r.readlines() for line in passwd: line = line.strip() size = len(line) print(size, line) r.close() ## Reading a file using `with` statement, automatically closes the file with open('/etc/passwd') as f: pass ## Writing to a file w = open('test.txt', 'w') w.write('127.0.0.1n') w.flush() lines = ['1.1.1.1n', '2.2.2.2n', '3.3.3.3n'] w.writelines(lines) w.close()

Handling Errors

All open related errors raises IOError exception.

try: f = open('/etc/passwd') except IOError as e: print ('Opps, something went wrong.') print (e)

Reading /etc/passwd and search each line for /bin/bash shell; when found print the line number and the line

#!/usr/bin/env python3 # working-with-files-01.py def main(): try: with open('/etc/passwd') as f: for no, line in enumerate(f, 1): if '/bin/bash' in line: line = line.strip() print(f'no> line>') except IOError as e: print(e) if __name__ == '__main__': main()

Using fileinput High-level module

fileinput module allows to quickly write a loop over standard input or a list of files.

Example
#!/usr/bin/env python3 # linescount-02.py import fileinput lines = 0 for line in fileinput.input(): lines += 1 print('totat lines:', lines)
$ cat /etc/passwd | python3 linescount.py totat lines: 86 $ python3 linescount.py /etc/services totat lines: 13921 $ python3 linescount.py /etc/services /etc/passwd /etc/hosts totat lines: 14023

By default, fileinput.input() will read all lines from files given as an argument to the script; if no arguments given then defaults to standard input.

Getting Started Command-line Arguments

sys module provides argv variable containing the list of arguments passed to the script when executed as a command-line application.

NOTE: The first argument sys.argv[0] is always the name of the script itself.

#!/usr/bin/env python3 # argv_01.py import sys print ('sys.argv:', sys.argv) print ('length:', len(argv))
$ python3 args_01.py --help ['argv-01.py', '--help'] 2 $ python3 args_01.py 1 2 3 ['argv-01.py', '1', '2', '3'] 4

Accept specific number of arguments and fail if not satistified.

#!/usr/bin/env python3 # args-02.py import sys # NOTE: [1:] excludes the first item at index 0, i.e script name argv_len = len(sys.argv[1:]) if not argv_len == 2: sys.exit(f'invalid number of arguments (expected 2, given: argv_len>)') print('two arguments are:', sys.argv[1:])
$ python args_02.py invalid number of arguments (expected 2, given: 0) $ python args_02.py 1 invalid number of arguments (expected 2, given: 1) $ python args_02.py 1 2 two arguments are: ['1', '2'] $ python args_02.py 1 2 3 invalid number of arguments (expected 2, given: 3)

Simple Implementation of `grep’ command

#!/usr/bin/env python3 # grep.py import sys script = sys.argv[0] def print_usage(): sys.exit(f'Usage: python script> pattern') def main(argv): if not len(argv) == 1: print_usage() pattern = argv[0] for line in sys.stdin: if pattern in line: print(line.strip()) if __name__ == '__main__': main(sys.argv[1:])
$ cat /etc/services | python3 grep.py 8080 http-alt 8080/udp # HTTP Alternate (see port 80) http-alt 8080/tcp # HTTP Alternate (see port 80)

Improvement Exercises

  • Extend grep.py to read from a file instead of standard input, and can be run as:
$ python3 grep.py 8080 /etc/services
  • Extend grep.py to read from a file if given as a second argument or default back to read from standard input similar to what grep does.
$ cat /etc/services | python3 grep.py 8080 # and also should works as $ python3 grep.py 8080 /etc/services

Exploring Standard Modules Operating System (OS) Module

Python built-in os module exposes operating system dependent functionality in a portable way, thus works across many different platforms.

Working with environmental variables:
  • os.environ a dictionary mapping system environment variables. e.g. os.environ.get(‘SHELL’)
  • os.getenv(key) retrieve a specific variable.
  • os.putenv(key, value) . change variable to specific value. e.g. os.putenv(‘HOME’, ‘/opt’)
Working with files and directories:
  • os.tmpnam returns a unique file name that can be used to create temporariry file. mktemp() from tempfile module is more secure.
  • os.mkdir(path) os.rmdir(path) os.chdir(path) os.listdir(path)
  • os.getcwd() returns current working directory as string. Similar to pwd command.
  • os.stat(path) similar to stat command
  • os.walk(path) recursively walk the dictionary tree, similar to ls -R . Returns generator yielding 3-tuple (dirpath, dirnames, files)
Example
>>> import os # environment variables >>> os.environ['SHELL'] # or os.environ.get('SHELL') or os.getenv('SHELL') 'bash' # Get a temporary filename using `tempfile` module >>> from tempfile import mktemp >>> temp = mktemp() '/var/folders/6s/4xn2fv852_1ghssypng0wwfw0000gn/T/tmp15O9aR' # Create the temporary file and write 'test' >>> with open(temp, 'w') as f: . f.write('testn') # Get the file stat, such as creation timestamp (ctime) >>> st = os.stat(temp) >>> st.st_ctime 1436466688.0 # convert timestamp to human readable format, we'll cover date & time later. >>> import datetime >>> d = datetime.datetime.fromtimestamp(st.st_ctime) >>> d.year # d.month, d.hour and so on. 2016
Working with Path names os.path :
  • os.path.abspath(path) get absolute path.
  • os.path.basename(path) get the filename excluding the directory part. Opposite of os.path.dirname which excludes filename part and returns directory path.
  • os.path.exists(path) returns True if path exists else False .
  • os.path.getsize(path) return size (in bytes) for a given path.
  • os.path.isfile(path) , os.path.isdir(path) returns True or False if path is file or a directory.
  • os.path.getctime(path) , os.path.getmtime(path) Similar to os.stat(path).ctime , os.stat(path).mtime()

Learn more at os.path documentation

Example
>>> os.path.isdir('/etc') True >>> os.chdir('/etc') >>> os.getcwd() '/etc' >>> os.path.abspath('hosts') '/etc/hosts' >>> os.path.isfile('/etc/hosts') True >>> os.path.getsize('/etc/hosts') 475 >>> print (os.path.basename('/etc/passwd')) 'passwd' >>> print (os.path.dirname('/etc/passwd')) '/etc'
Process related functions:
  • os.getpid() get id of current process and os.getppid() to get parent process id.
  • os.system(command) execute a command and returns exit code.
Getting System Informations:
  • os.uname() returns a 5-tuple (sysname, nodename, release, version, machine) identifying the current OS. Similar to uname -a command.
  • os.getloadavg() returns 3-tuple containing 1-min, 5-min and 15-min load average.

Print size (in bytes) of all files in a given directory

#!/usr/bin/env python3 # filesizes.py import os import sys script = sys.argv[0] def print_usage(): print(f' >> sys.stderr>, "Usage: python3 script> DIR"') sys.exit(1) def filesizes(path): ''' calculate and print size of each file in a given directory. ''' for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: filepath = os.path.join(dirpath, filename) _bytes = os.path.getsize(filepath) print (f'_bytes>, filepath>') def main(argv): if not len(argv) == 1: print_usage() path = argv[0] filesizes(path) if __name__ == '__main__': main(sys.argv[1:])
$ python3 filesizes.py . 678 ./filesizes.py ``` 

Learn more about OS module

Exploring Standard Modules System-specific Module

Python built-in sys module exposes system-specific parameters and functions. This module provides access to some variables used or maintained by the interpreter and functions that interact strongly with the interpreter. sys module is always available.

Commonly used variables and functions:
  • sys.argv contains list of command-line arguments. Already covered.
  • sys.exit([arg]) exit the program. arg is optional, can be 0 to indicate success, > 0 for failure or string to display the errors during exit.
  • sys.version stores version of Python installed.
  • sys.stdin sys.stdout sys.stderr File objects corresponding to the interpreter’s standard input, output and error pipes.
  • sys.platform stored the name of the platofrm Python is running. Such as darwin for MacOS, linux for Linux and others
  • sys.path A list of strings that specified the search path while importing modules via import statement.
  • sys.modules A dictionary mapping the < 'module_name': 'module_path', . >which have already been loaded.
#!/usr/bin/env python3 # sys-01.py import sys from sys import argv print (f''' Python version installed: sys.version> Python running on platforn: sys.platform> ''') if len(argv) == 10: sys.exit('error: too many arguments') print(f''' argv = argv> len(argv) = len(argv)> ''') print ('Printing to stdout') print (f'>> sys.stderr>, "Printing to stderr"') print(f''' total modules search path: len(sys.path)> total modules loaded: len(sys.modules)> ''') # success sys.exit(0)
Output should look like this
$ python3 sys-01.py Python version installed: 3.7.4 (default, Jul 9 2019, 16:48:28) [GCC 8.3.1 20190223 (Red Hat 8.3.1-2)] Python running on platforn: linux argv = ['sys_01.py'] len(argv) = 1 Printing to stdout >> _io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, "Printing to stderr" total modules search path: 7 total modules loaded: 57 $ echo $? 0

Learn more about sys module

Exploring Standard Modules Shell Modules

shutil module — High-level file operations

The shutil module provides high-level operations on files or collection of files.

Copy Operations:
  • shutil.copy(src, dst) Copy src file to dst file or directory.
  • shutil.copymode(src, dst) Copy permission mode of src file to dst file.
  • shutil.copystat(src, dst) Copy permission mode, modification and creation date from src file to dst file.
  • shutil.copy2(src, dst) Similar to cp -p command or equivalent of shutil.copy and shutil.copystat .
Move Operations:
  • shutil.move(src, dst) Move src file to dst file or directory.

Learn more about shutil module

glob module — Unix style pathname pattern expansion

The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell.

  • glob.glob(pattern) Return a list of path names that match the path pattern. Path can be absolute /usr/local/bin/*.py or relative local/bin/*.py .
Example
>>> import glob >>> glob.glob('/etc/sysconfig/network-scripts/ifcfg*') ['/etc/sysconfig/network-scripts/ifcfg-venet0', '/etc/sysconfig/network-scripts/ifcfg-lo'] >>> glob.glob('/etc/*.conf') ['/etc/vnstat.conf', '/etc/sudo.conf', '/etc/resolv.conf', '/etc/host.conf', '/etc/logrotate.conf']

Learn more about glob module

Exploring Standard Modules Date and Time Modules

time module — Clock time

The time module exposes the time-related functions from the underlying C library.

Commonly used functions:
  • time.time() returns the number of seconds since the start of the epoch as a floating-point value.
  • time.ctime() returns a human-friendly date and time representation.
  • time.gmtime() returns an object containing current time in UTC format.
  • time.localtime() returns an object containing the current time in current time zone.
  • time.tzset() sets the time zone based on TZ environment variable: os.environ.get(‘TZ’)
Example
>>> import time >>> time.time() 1459924583.396017 >>> # current time in UTC >>> utc = time.gmtime() >>> dir(utc) ['tm_hour', 'tm_isdst', 'tm_mday', 'tm_min', 'tm_mon', 'tm_sec', 'tm_wday', 'tm_yday', 'tm_year'] >>> # current time in GMT by updating timezone >>> import os >>> os.putenv('TZ', 'GMT') # or os.environ['TZ'] = 'GMT' >>> time.tzset() >>> gmt = '<> <>'.format(time.ctime(), time.tzname[0])

Learn more about time module

datetime module — Date and Time Value Manipulation

The datetime module includes functions and classes for doing date and time parsing, formatting, and arithmetic.

Commonly used functions:
  • datetime.date.today() returns current date object without the time
  • datetime.datetime.today() returns current date and time object
  • datetime.datetime.fromtimestamp(float) convert unix timestamp to datetime object
  • datetime.timedelta future and past dates can be calculated using basic arithmetic (+, -) on two datetime objects, or by combining a datetime with a timedelta object.
Example
>>> import datetime >>> today_date = datetime.date.today() >>> ten_days = datetime.timedelta(days=10) >>> today_date - ten_days # past >>> today_date + ten_days # future
Alternate formats can be generated using strftime() and strptime to convert formatted string to datetime object.
>>> import datetime # convert datetime to custom format >>> format = "%a %b %d %H:%M:%S %Y" >>> today = datetime.datetime.today() >>> today.strftime(format) 'Mon Oct 14 17:56:24 2019' # convert formatted string to datetime object >>> datetime.datetime.strptime('Mon Oct 14 17:56:24 2019', format) datetime.datetime(2019, 10, 14, 17, 56, 24)

Learn more about datetime module

Exploring Standard Modules Subprocess Module

subprocess module — Subprocess management

The subprocess module allows to run new processes, connect to their input/output/error pipes, and obtain their return codes.

The module defines a many helper functions and a class called Popen which allows to set up the new process so the parent can communicate with it via pipes.

Running external commands

To run an external command without interacting with, use subprocess.call(command, shell=True) function.

>>> import subprocess >>> rc = subprocess.call('ls -l /etc', shell=True) 0 >>> rc = subprocess.call('ls -l no_such_file.txt', shell=True) 1

Setting the shell argument to a True value causes subprocess to spawn a shell process (normally bash), which then runs the command. Using a shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run.

>>> import subprocess >>> subprocess.call('echo $PATH' ) # will return error subprocess.call('echo $PATH', shell=True) # will print the shell PATH variable value

Error Handling

The return value from subprocess.call() is the exit code of the program and is used to detect errors. The subprocess.check_call() function works like call() , except that the exit code is checked, and if it returns non-zero, then a subprocess.CalledProcessError exception is raised.

#!/usr/bin/env python3 # check_call.py import sys import subprocess try: cmd = 'false' print ('running command:',cmd) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as error: sys.exit(f'error: error>')
$ python3 check_call.py running command: false error: Command 'false' returned non-zero exit status 1

Capturing Command Output

To run an external command and capture it’s output, use check_output(command, shell=True) to capture the output for later processing. If command returns non-zero, then a CalledProcessError exception is raised similar to check_call .

Execute cat /etc/hosts and write the output to a file hosts.txt

#!/usr/bin/env python3 # capture_output.py import subprocess import sys try: cmd = 'cat /etc/hosts' print('running command:', cmd) output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as error: sys.exit('error: ') else: print('success!') with open('hosts.txt', 'w') as f: f.write(output) #this should give an error in python3.6+

By default, check_output captures outputs written to stdout . Setting the stderr=subprocess.STDOUT causes stderr outputs to redirected to stdout , so errors can be captured as well.

Working directory with Popen

The call() , check_call() , and check_output() are wrappers around the Popen class. Using Popen directly gives more control over how the command is run and how its input and output streams are processed.

One-Way Communication with a Process

To run a process and capture it’s output, set the stdout and stderr arguments to subprocess.PIPE and call communicate() .

communicate() returns 2-tuple (stderr_output, stderr_putput)

#!/usr/bin/env python3 # one-way.py import subprocess import sys script = sys.argv[0] def main(argv): if not len(argv) == 1: sys.exit(f'usage: python3 script> command') cmd = sys.argv[1] print ('running command:', cmd) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() print(f''' exit code: proc.poll()> stdout: stdout or None> stderr: stderr or None> ''') if __name__ == '__main__': main(sys.argv[1:])
$ python3 one_way.py ls running command: ls exit code: 0 stdout: b'capture_output.pyncheck_call.pynhosts.txtnone_way.pynsys_01.pyn' stderr: None

Bidirectional Communication with a Process

To set up the Popen instance for reading and writing at the same time, pass additional argument stdin=subprocess.PIPE .

#!/usr/bin/env python3 # bidirectional.py import subprocess from subprocess import PIPE import sys cmd = 'bc' send = '1 + 1n' print('running command:', cmd, 'and sending input:', send) proc = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = proc.communicate(send) print(f''' exit code: proc.poll()> stdin: send> stdout: stdout or None> stderr: stderr or None> ''')
$ python3 bidirectional.py running command: bc and sending input: 1 + 1 exit code: 0 stdin: 1 + 1 stdout: 2 stderr: None

Learn more about subprocess module

Exploring Argparse Command-Line Option and Argument Parsing

Python built-in argparse is parser for command-line options, arguments and subcommands. The argparse module provides argument management just like sys.argv , but with options, e.g it generates help and usage messages and issues errors when users give the program invalid arguments.
Let’s show the sort of functionality by making use of the ls command:

$ ls examples LICENSE README.md $ ls -l total 44 drwxrwxr-x. 4 que que 4096 Oct 14 18:05 . drwxrwxr-x. 24 que que 4096 Oct 13 15:32 .. drwxrwxr-x. 2 que que 4096 Oct 14 18:48 examples drwxrwxr-x. 8 que que 4096 Oct 15 01:01 .git -rw-rw-r--. 1 que que 1210 Oct 13 15:32 LICENSE -rw-rw-r--. 1 que que 24357 Oct 15 01:02 README.md $ ls --help Usage: ls [OPTION]. [FILE]. List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. .

A few concepts we can learn from the four commands:

  • When you run the «ls -l» command with options, it will default displaying the contents of the current directory
  • The «-l» is knowns as an «optional argument»
  • If you want to display the help text of the ls command, you would type «ls —help»

To start using the argparse module, we first have to import it.

Intro to positional arguments

The following code is a Python program that takes a list of integers and produces either the sum or the max:

Example
#!/usr/bin/env python3 #app.py import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') args = parser.parse_args() print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called app.py , it can be run at the command line and provides useful help messages

$ app.py -h usage: prog.py [-h] [--sum] N [N . ] Process some integers. positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) $ app.py 1 2 3 4 4 $ app.py 1 2 3 4 --sum 10

Creating a parser

The first step in using the argparse is creating an ArgumentParser object:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

The ArgumentParser object will hold all the information necessary to parse the command line into python data types.

Adding arguments

Filling an ArgumentParser with information about program arguments is done by making calls to the ArgumentParser.add_argument method. Generally, these calls tell the ArgumentParser how to take the strings on the command line and turn them into objects. This information is stored and used when ArgumentParser.parse_args is called. For example:

>>> parser.add_argument('integers', metavar='N', type=int, nargs='+', . help='an integer for the accumulator') >>> parser.add_argument('--sum', dest='accumulate', action='store_const', . const=sum, default=max, . help='sum the integers (default: find the max)')

Later, calling parse_args will return an object with two attributes, integers and accumulate. The integers attribute will be a list of one or more ints, and the accumulate attribute will be either the sum function, if —sum was specified at the command line, or the max function if it was not.

Parsing arguments

ArgumentParser parses args through the ArgumentParser.parse_args method. This will inspect the command-line, convert each arg to the appropriate type and then invoke the appropriate action. In most cases, this means a simple namespace object will be built up from attributes parsed out of the command-line:

>>> parser.parse_args(['--sum', '7', '-1', '42']) Namespace(accumulate=built-in function sum>, integers=[7, -1, 42])

In a script, ArgumentParser.parse_args will typically be called with no arguments, and the ArgumentParser will automatically determine the command-line args from sys.argv .

ArgumentParser objects

Create a new ArgumentParser object. Each parameter has its own more detailed description below, but in short they are:

  • description — Text to display before the argument help.
  • epilog — Text to display after the argument help.
  • add_help — Add a -h/—help option to the parser. (default: True)
  • argument_default — Set the global default value for arguments. (default: None)
  • parents — A list of ArgumentParser objects whose arguments should also be included.
  • prefix_chars — The set of characters that prefix optional arguments. (default: ‘-‘)
  • fromfile_prefix_chars — The set of characters that prefix files from which additional arguments should be read. (default: None)
  • formatter_class — A class for customizing the help output.
  • conflict_handler — Usually unnecessary, defines strategy for resolving conflicting optionals.
  • prog — The name of the program (default: sys.argv[0] )
  • usage — The string describing the program usage (default: generated)

Learn more about argparse module

Exploring SQLite Module exploring-standard-modules-embedded-relational-database-module

SQLite is a C-language library that implements a SQL like database engine which is relatively quick, serverless and self-contained, high-reliable. SQLite comes built-in with most of the moden software, hardware devices and browsers, thus Python also has embedded SQLite engine named sqlite3.

To Start using the sqlite3 library:

Commonly used functions:

  • sqlite3.connect() — A connection object is created using the connect() function e.g connection = sqlite.connect(‘name_of_file_db.db’)
  • connection.cursor() — To execute SQLite statements, cursor object is needed. You can create it using the cursor() method. e.g cursor_object = connection.cursor()
  • connection.execute() — To create a table in SQLite3, you can use the Create Table, Insert Into Table, Update Table, or Select query with the execute() method of SQLite library. For example cursor_object.execute(«CREATE TABLE employees()»); connection.commit()
  • connection.commit() — The commit() method saves all the changes we make.
  • cursor_object.fetchall() — To fetch the data from a database we will execute the SELECT statement and then will use the fetchall() method of the cursor object to store the values into a variable, e.g cursor_object.execute(‘SELECT * FROM employees’) ; rows = cursor_object.fetchall()
  • cursor_object.rowcount() — The SQLite3 rowcount is used to return the number of rows that are affected or selected by the latest executed SQL query
  • cursor_object.executemany() — It can use the executemany statement to insert multiple rows at once.
  • connection.close() — You are done with your database, it is a good practice to close the connection with close() method. e.g. connection.close()

Learn More about SQLite3 Module

Exploring XmlTree Module exploring-xmltree-module

Learn More about XmlTree Module

Exploring JSON Module exploring-json-module

JSON is text, written with JavaScript object notation. JSON is a syntax for storing and exchanging data.
It is commonly used for transmitting data in web applications (e.g., sending some data from the server to the client, so it can be displayed on a web page
and vice versa

  • json.loads()
  • take a file object and returns the json object. A JSON object contains data in the form of key/value pair. The keys are strings and the values are the JSON types
  • json.dumps()
    -json.dumps() function converts a Python object into a json string
    .It is the exact opposite of json.loads.

THIS IS THE ENCODING DECODING LIST

1)object- DICT
2)array — list
3)string — str
4)int — int
5)real — float
6)true — true
7)False — False
8)NULL — NONE

  • Encoding is from python to JSON(final type)
  • Decoding is from JSON to python(final type)

Encoding functions

  • iterencode(o)
    -Encode the given object, o, and yield each string representation as available. For example:

for chunk in json.JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)]

-sort-keys -Sort the output of dictionaries alphabetically by key.

-h, —help¶ — help box

infile -to check your Json file for syntax

outfile -Write the output of the infile to the given outfile

Note

If the optional infile and outfile arguments are not specified, sys.stdin and sys.stdout will be used respectively:

json.tool — to validate and pretty-print JSON objects.

raw_decode — This can be used to decode a JSON document from a string that may have extraneous data at the end.

Learn More about JSON Module

Python3 for Systems Administrator

Contents

Getting Started Standard Input, Output and Error

Standard input, output and error (commonly referred to as stdin , stdout and stderr ) are what’s called pipes.

These pipes are normally connected to the terminal window where you are working.

When printing something (using print() ), it goes to the stdout pipe by default; when your program needs to print errors (like a traceback in Python), it goes to the stderr pipe; and when your program requires input from a user or other programs, it goes to the stdin pipe.

$ cat /etc/passwd | grep /bin/bash # `_ writes to stdout `_ reads from stdin $ ls no_such_file.txt # `_ writes to stderr

Python built-in sys module provides stdin , stdout and stderr as a file-objects, exposing read() , readlines() , write() , writelines() methods, as shown below:

#!/usr/bin/env python3 import sys # writing to stdout pipe print ('Hello, world') sys.stdout.write('Hello, worldn') # writing to stderr pipe print("Error occured") sys.stderr.write("Error occuredn") # reading single line from stdin pipe sys.stdout.write('Username: ') username = sys.stdin.readline() print (username) # reading 'n' number of characters from stdin print ('Enter few characters and press Ctrl-D') data = sys.stdin.read(1024) print('len(data):', len(data)) # reading lines (separated by newlines) from stdin print('Enter few lines and press Ctrl-D') lines = sys.stdin.readlines() print ('total lines read:', len(lines))

Getting Started Working with files

Python built-in open function is the standard interface for working with files. open returns a file object with familiar methods for performing read/write operations.

Common arguments:
  • file: absolute or relative path of the file. e.g: /etc/passwd , ./ip-list.txt
  • mode: an optional string specifying mode in which the file is opened. Default’s to r for reading in text mode. Common values are:
  • w write only (truncates the file already exists)
  • x create and write to a new file (if file already exists then open fails)
  • a append to a file (insert data to end of the file)
  • + updating a file (reading and writing). e.g: r+ w+
  • b binary mode for non-text files. Contents are returned as byte objects.
  • t text mode (default). Contents are returned as strings .
File object methods:
  • .close()
  • .read(size=-1) read at most n characters. If n is negative or ommited, reads the whole file until EOF .
  • .readline() Read single line until newline or EOF .
  • .readlines() Read all newlines and returns as a list.
  • .write(data) Write data to file. Returns number of characters written.
  • .writelines(list) Write all data in the list. Useful for writing multiple lines to a file.
Example
## Reading a file r = open('/etc/passwd') # same as: # r = open('/etc/passwd', 'r') passwd = r.readlines() for line in passwd: line = line.strip() size = len(line) print(size, line) r.close() ## Reading a file using `with` statement, automatically closes the file with open('/etc/passwd') as f: pass ## Writing to a file w = open('test.txt', 'w') w.write('127.0.0.1n') w.flush() lines = ['1.1.1.1n', '2.2.2.2n', '3.3.3.3n'] w.writelines(lines) w.close()

Handling Errors

All open related errors raises IOError exception.

try: f = open('/etc/passwd') except IOError as e: print ('Opps, something went wrong.') print (e)

Reading /etc/passwd and search each line for /bin/bash shell; when found print the line number and the line

#!/usr/bin/env python3 # working-with-files-01.py def main(): try: with open('/etc/passwd') as f: for no, line in enumerate(f, 1): if '/bin/bash' in line: line = line.strip() print(f'no> line>') except IOError as e: print(e) if __name__ == '__main__': main()

Using fileinput High-level module

fileinput module allows to quickly write a loop over standard input or a list of files.

Example
#!/usr/bin/env python3 # linescount-02.py import fileinput lines = 0 for line in fileinput.input(): lines += 1 print('totat lines:', lines)
$ cat /etc/passwd | python3 linescount.py totat lines: 86 $ python3 linescount.py /etc/services totat lines: 13921 $ python3 linescount.py /etc/services /etc/passwd /etc/hosts totat lines: 14023

By default, fileinput.input() will read all lines from files given as an argument to the script; if no arguments given then defaults to standard input.

Getting Started Command-line Arguments

sys module provides argv variable containing the list of arguments passed to the script when executed as a command-line application.

NOTE: The first argument sys.argv[0] is always the name of the script itself.

#!/usr/bin/env python3 # argv_01.py import sys print ('sys.argv:', sys.argv) print ('length:', len(argv))
$ python3 args_01.py --help ['argv-01.py', '--help'] 2 $ python3 args_01.py 1 2 3 ['argv-01.py', '1', '2', '3'] 4

Accept specific number of arguments and fail if not satistified.

#!/usr/bin/env python3 # args-02.py import sys # NOTE: [1:] excludes the first item at index 0, i.e script name argv_len = len(sys.argv[1:]) if not argv_len == 2: sys.exit(f'invalid number of arguments (expected 2, given: argv_len>)') print('two arguments are:', sys.argv[1:])
$ python args_02.py invalid number of arguments (expected 2, given: 0) $ python args_02.py 1 invalid number of arguments (expected 2, given: 1) $ python args_02.py 1 2 two arguments are: ['1', '2'] $ python args_02.py 1 2 3 invalid number of arguments (expected 2, given: 3)

Simple Implementation of `grep’ command

#!/usr/bin/env python3 # grep.py import sys script = sys.argv[0] def print_usage(): sys.exit(f'Usage: python script> pattern') def main(argv): if not len(argv) == 1: print_usage() pattern = argv[0] for line in sys.stdin: if pattern in line: print(line.strip()) if __name__ == '__main__': main(sys.argv[1:])
$ cat /etc/services | python3 grep.py 8080 http-alt 8080/udp # HTTP Alternate (see port 80) http-alt 8080/tcp # HTTP Alternate (see port 80)

Improvement Exercises

  • Extend grep.py to read from a file instead of standard input, and can be run as:
$ python3 grep.py 8080 /etc/services
  • Extend grep.py to read from a file if given as a second argument or default back to read from standard input similar to what grep does.
$ cat /etc/services | python3 grep.py 8080 # and also should works as $ python3 grep.py 8080 /etc/services

Exploring Standard Modules Operating System (OS) Module

Python built-in os module exposes operating system dependent functionality in a portable way, thus works across many different platforms.

Working with environmental variables:
  • os.environ a dictionary mapping system environment variables. e.g. os.environ.get(‘SHELL’)
  • os.getenv(key) retrieve a specific variable.
  • os.putenv(key, value) . change variable to specific value. e.g. os.putenv(‘HOME’, ‘/opt’)
Working with files and directories:
  • os.tmpnam returns a unique file name that can be used to create temporariry file. mktemp() from tempfile module is more secure.
  • os.mkdir(path) os.rmdir(path) os.chdir(path) os.listdir(path)
  • os.getcwd() returns current working directory as string. Similar to pwd command.
  • os.stat(path) similar to stat command
  • os.walk(path) recursively walk the dictionary tree, similar to ls -R . Returns generator yielding 3-tuple (dirpath, dirnames, files)
Example
>>> import os # environment variables >>> os.environ['SHELL'] # or os.environ.get('SHELL') or os.getenv('SHELL') 'bash' # Get a temporary filename using `tempfile` module >>> from tempfile import mktemp >>> temp = mktemp() '/var/folders/6s/4xn2fv852_1ghssypng0wwfw0000gn/T/tmp15O9aR' # Create the temporary file and write 'test' >>> with open(temp, 'w') as f: . f.write('testn') # Get the file stat, such as creation timestamp (ctime) >>> st = os.stat(temp) >>> st.st_ctime 1436466688.0 # convert timestamp to human readable format, we'll cover date & time later. >>> import datetime >>> d = datetime.datetime.fromtimestamp(st.st_ctime) >>> d.year # d.month, d.hour and so on. 2016
Working with Path names os.path :
  • os.path.abspath(path) get absolute path.
  • os.path.basename(path) get the filename excluding the directory part. Opposite of os.path.dirname which excludes filename part and returns directory path.
  • os.path.exists(path) returns True if path exists else False .
  • os.path.getsize(path) return size (in bytes) for a given path.
  • os.path.isfile(path) , os.path.isdir(path) returns True or False if path is file or a directory.
  • os.path.getctime(path) , os.path.getmtime(path) Similar to os.stat(path).ctime , os.stat(path).mtime()

Learn more at os.path documentation

Example
>>> os.path.isdir('/etc') True >>> os.chdir('/etc') >>> os.getcwd() '/etc' >>> os.path.abspath('hosts') '/etc/hosts' >>> os.path.isfile('/etc/hosts') True >>> os.path.getsize('/etc/hosts') 475 >>> print (os.path.basename('/etc/passwd')) 'passwd' >>> print (os.path.dirname('/etc/passwd')) '/etc'
Process related functions:
  • os.getpid() get id of current process and os.getppid() to get parent process id.
  • os.system(command) execute a command and returns exit code.
Getting System Informations:
  • os.uname() returns a 5-tuple (sysname, nodename, release, version, machine) identifying the current OS. Similar to uname -a command.
  • os.getloadavg() returns 3-tuple containing 1-min, 5-min and 15-min load average.

Print size (in bytes) of all files in a given directory

#!/usr/bin/env python3 # filesizes.py import os import sys script = sys.argv[0] def print_usage(): print(f' >> sys.stderr>, "Usage: python3 script> DIR"') sys.exit(1) def filesizes(path): ''' calculate and print size of each file in a given directory. ''' for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: filepath = os.path.join(dirpath, filename) _bytes = os.path.getsize(filepath) print (f'_bytes>, filepath>') def main(argv): if not len(argv) == 1: print_usage() path = argv[0] filesizes(path) if __name__ == '__main__': main(sys.argv[1:])
$ python3 filesizes.py . 678 ./filesizes.py ``` 

Learn more about OS module

Exploring Standard Modules System-specific Module

Python built-in sys module exposes system-specific parameters and functions. This module provides access to some variables used or maintained by the interpreter and functions that interact strongly with the interpreter. sys module is always available.

Commonly used variables and functions:
  • sys.argv contains list of command-line arguments. Already covered.
  • sys.exit([arg]) exit the program. arg is optional, can be 0 to indicate success, > 0 for failure or string to display the errors during exit.
  • sys.version stores version of Python installed.
  • sys.stdin sys.stdout sys.stderr File objects corresponding to the interpreter’s standard input, output and error pipes.
  • sys.platform stored the name of the platofrm Python is running. Such as darwin for MacOS, linux for Linux and others
  • sys.path A list of strings that specified the search path while importing modules via import statement.
  • sys.modules A dictionary mapping the < 'module_name': 'module_path', . >which have already been loaded.
#!/usr/bin/env python3 # sys-01.py import sys from sys import argv print (f''' Python version installed: sys.version> Python running on platforn: sys.platform> ''') if len(argv) == 10: sys.exit('error: too many arguments') print(f''' argv = argv> len(argv) = len(argv)> ''') print ('Printing to stdout') print (f'>> sys.stderr>, "Printing to stderr"') print(f''' total modules search path: len(sys.path)> total modules loaded: len(sys.modules)> ''') # success sys.exit(0)
Output should look like this
$ python3 sys-01.py Python version installed: 3.7.4 (default, Jul 9 2019, 16:48:28) [GCC 8.3.1 20190223 (Red Hat 8.3.1-2)] Python running on platforn: linux argv = ['sys_01.py'] len(argv) = 1 Printing to stdout >> _io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, "Printing to stderr" total modules search path: 7 total modules loaded: 57 $ echo $? 0

Learn more about sys module

Exploring Standard Modules Shell Modules

shutil module — High-level file operations

The shutil module provides high-level operations on files or collection of files.

Copy Operations:
  • shutil.copy(src, dst) Copy src file to dst file or directory.
  • shutil.copymode(src, dst) Copy permission mode of src file to dst file.
  • shutil.copystat(src, dst) Copy permission mode, modification and creation date from src file to dst file.
  • shutil.copy2(src, dst) Similar to cp -p command or equivalent of shutil.copy and shutil.copystat .
Move Operations:
  • shutil.move(src, dst) Move src file to dst file or directory.

Learn more about shutil module

glob module — Unix style pathname pattern expansion

The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell.

  • glob.glob(pattern) Return a list of path names that match the path pattern. Path can be absolute /usr/local/bin/*.py or relative local/bin/*.py .
Example
>>> import glob >>> glob.glob('/etc/sysconfig/network-scripts/ifcfg*') ['/etc/sysconfig/network-scripts/ifcfg-venet0', '/etc/sysconfig/network-scripts/ifcfg-lo'] >>> glob.glob('/etc/*.conf') ['/etc/vnstat.conf', '/etc/sudo.conf', '/etc/resolv.conf', '/etc/host.conf', '/etc/logrotate.conf']

Learn more about glob module

Exploring Standard Modules Date and Time Modules

time module — Clock time

The time module exposes the time-related functions from the underlying C library.

Commonly used functions:
  • time.time() returns the number of seconds since the start of the epoch as a floating-point value.
  • time.ctime() returns a human-friendly date and time representation.
  • time.gmtime() returns an object containing current time in UTC format.
  • time.localtime() returns an object containing the current time in current time zone.
  • time.tzset() sets the time zone based on TZ environment variable: os.environ.get(‘TZ’)
Example
>>> import time >>> time.time() 1459924583.396017 >>> # current time in UTC >>> utc = time.gmtime() >>> dir(utc) ['tm_hour', 'tm_isdst', 'tm_mday', 'tm_min', 'tm_mon', 'tm_sec', 'tm_wday', 'tm_yday', 'tm_year'] >>> # current time in GMT by updating timezone >>> import os >>> os.putenv('TZ', 'GMT') # or os.environ['TZ'] = 'GMT' >>> time.tzset() >>> gmt = '<> <>'.format(time.ctime(), time.tzname[0])

Learn more about time module

datetime module — Date and Time Value Manipulation

The datetime module includes functions and classes for doing date and time parsing, formatting, and arithmetic.

Commonly used functions:
  • datetime.date.today() returns current date object without the time
  • datetime.datetime.today() returns current date and time object
  • datetime.datetime.fromtimestamp(float) convert unix timestamp to datetime object
  • datetime.timedelta future and past dates can be calculated using basic arithmetic (+, -) on two datetime objects, or by combining a datetime with a timedelta object.
Example
>>> import datetime >>> today_date = datetime.date.today() >>> ten_days = datetime.timedelta(days=10) >>> today_date - ten_days # past >>> today_date + ten_days # future
Alternate formats can be generated using strftime() and strptime to convert formatted string to datetime object.
>>> import datetime # convert datetime to custom format >>> format = "%a %b %d %H:%M:%S %Y" >>> today = datetime.datetime.today() >>> today.strftime(format) 'Mon Oct 14 17:56:24 2019' # convert formatted string to datetime object >>> datetime.datetime.strptime('Mon Oct 14 17:56:24 2019', format) datetime.datetime(2019, 10, 14, 17, 56, 24)

Learn more about datetime module

Exploring Standard Modules Subprocess Module

subprocess module — Subprocess management

The subprocess module allows to run new processes, connect to their input/output/error pipes, and obtain their return codes.

The module defines a many helper functions and a class called Popen which allows to set up the new process so the parent can communicate with it via pipes.

Running external commands

To run an external command without interacting with, use subprocess.call(command, shell=True) function.

>>> import subprocess >>> rc = subprocess.call('ls -l /etc', shell=True) 0 >>> rc = subprocess.call('ls -l no_such_file.txt', shell=True) 1

Setting the shell argument to a True value causes subprocess to spawn a shell process (normally bash), which then runs the command. Using a shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run.

>>> import subprocess >>> subprocess.call('echo $PATH' ) # will return error subprocess.call('echo $PATH', shell=True) # will print the shell PATH variable value

Error Handling

The return value from subprocess.call() is the exit code of the program and is used to detect errors. The subprocess.check_call() function works like call() , except that the exit code is checked, and if it returns non-zero, then a subprocess.CalledProcessError exception is raised.

#!/usr/bin/env python3 # check_call.py import sys import subprocess try: cmd = 'false' print ('running command:',cmd) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as error: sys.exit(f'error: error>')
$ python3 check_call.py running command: false error: Command 'false' returned non-zero exit status 1

Capturing Command Output

To run an external command and capture it’s output, use check_output(command, shell=True) to capture the output for later processing. If command returns non-zero, then a CalledProcessError exception is raised similar to check_call .

Execute cat /etc/hosts and write the output to a file hosts.txt

#!/usr/bin/env python3 # capture_output.py import subprocess import sys try: cmd = 'cat /etc/hosts' print('running command:', cmd) output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as error: sys.exit('error: ') else: print('success!') with open('hosts.txt', 'w') as f: f.write(output) #this should give an error in python3.6+

By default, check_output captures outputs written to stdout . Setting the stderr=subprocess.STDOUT causes stderr outputs to redirected to stdout , so errors can be captured as well.

Working directory with Popen

The call() , check_call() , and check_output() are wrappers around the Popen class. Using Popen directly gives more control over how the command is run and how its input and output streams are processed.

One-Way Communication with a Process

To run a process and capture it’s output, set the stdout and stderr arguments to subprocess.PIPE and call communicate() .

communicate() returns 2-tuple (stderr_output, stderr_putput)

#!/usr/bin/env python3 # one-way.py import subprocess import sys script = sys.argv[0] def main(argv): if not len(argv) == 1: sys.exit(f'usage: python3 script> command') cmd = sys.argv[1] print ('running command:', cmd) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() print(f''' exit code: proc.poll()> stdout: stdout or None> stderr: stderr or None> ''') if __name__ == '__main__': main(sys.argv[1:])
$ python3 one_way.py ls running command: ls exit code: 0 stdout: b'capture_output.pyncheck_call.pynhosts.txtnone_way.pynsys_01.pyn' stderr: None

Bidirectional Communication with a Process

To set up the Popen instance for reading and writing at the same time, pass additional argument stdin=subprocess.PIPE .

#!/usr/bin/env python3 # bidirectional.py import subprocess from subprocess import PIPE import sys cmd = 'bc' send = '1 + 1n' print('running command:', cmd, 'and sending input:', send) proc = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = proc.communicate(send) print(f''' exit code: proc.poll()> stdin: send> stdout: stdout or None> stderr: stderr or None> ''')
$ python3 bidirectional.py running command: bc and sending input: 1 + 1 exit code: 0 stdin: 1 + 1 stdout: 2 stderr: None

Learn more about subprocess module

Exploring Argparse Command-Line Option and Argument Parsing

Python built-in argparse is parser for command-line options, arguments and subcommands. The argparse module provides argument management just like sys.argv , but with options, e.g it generates help and usage messages and issues errors when users give the program invalid arguments.
Let’s show the sort of functionality by making use of the ls command:

$ ls examples LICENSE README.md $ ls -l total 44 drwxrwxr-x. 4 que que 4096 Oct 14 18:05 . drwxrwxr-x. 24 que que 4096 Oct 13 15:32 .. drwxrwxr-x. 2 que que 4096 Oct 14 18:48 examples drwxrwxr-x. 8 que que 4096 Oct 15 01:01 .git -rw-rw-r--. 1 que que 1210 Oct 13 15:32 LICENSE -rw-rw-r--. 1 que que 24357 Oct 15 01:02 README.md $ ls --help Usage: ls [OPTION]. [FILE]. List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. .

A few concepts we can learn from the four commands:

  • When you run the «ls -l» command with options, it will default displaying the contents of the current directory
  • The «-l» is knowns as an «optional argument»
  • If you want to display the help text of the ls command, you would type «ls —help»

To start using the argparse module, we first have to import it.

Intro to positional arguments

The following code is a Python program that takes a list of integers and produces either the sum or the max:

Example
#!/usr/bin/env python3 #app.py import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') args = parser.parse_args() print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called app.py , it can be run at the command line and provides useful help messages

$ app.py -h usage: prog.py [-h] [--sum] N [N . ] Process some integers. positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) $ app.py 1 2 3 4 4 $ app.py 1 2 3 4 --sum 10

Creating a parser

The first step in using the argparse is creating an ArgumentParser object:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

The ArgumentParser object will hold all the information necessary to parse the command line into python data types.

Adding arguments

Filling an ArgumentParser with information about program arguments is done by making calls to the ArgumentParser.add_argument method. Generally, these calls tell the ArgumentParser how to take the strings on the command line and turn them into objects. This information is stored and used when ArgumentParser.parse_args is called. For example:

>>> parser.add_argument('integers', metavar='N', type=int, nargs='+', . help='an integer for the accumulator') >>> parser.add_argument('--sum', dest='accumulate', action='store_const', . const=sum, default=max, . help='sum the integers (default: find the max)')

Later, calling parse_args will return an object with two attributes, integers and accumulate. The integers attribute will be a list of one or more ints, and the accumulate attribute will be either the sum function, if —sum was specified at the command line, or the max function if it was not.

Parsing arguments

ArgumentParser parses args through the ArgumentParser.parse_args method. This will inspect the command-line, convert each arg to the appropriate type and then invoke the appropriate action. In most cases, this means a simple namespace object will be built up from attributes parsed out of the command-line:

>>> parser.parse_args(['--sum', '7', '-1', '42']) Namespace(accumulate=built-in function sum>, integers=[7, -1, 42])

In a script, ArgumentParser.parse_args will typically be called with no arguments, and the ArgumentParser will automatically determine the command-line args from sys.argv .

ArgumentParser objects

Create a new ArgumentParser object. Each parameter has its own more detailed description below, but in short they are:

  • description — Text to display before the argument help.
  • epilog — Text to display after the argument help.
  • add_help — Add a -h/—help option to the parser. (default: True)
  • argument_default — Set the global default value for arguments. (default: None)
  • parents — A list of ArgumentParser objects whose arguments should also be included.
  • prefix_chars — The set of characters that prefix optional arguments. (default: ‘-‘)
  • fromfile_prefix_chars — The set of characters that prefix files from which additional arguments should be read. (default: None)
  • formatter_class — A class for customizing the help output.
  • conflict_handler — Usually unnecessary, defines strategy for resolving conflicting optionals.
  • prog — The name of the program (default: sys.argv[0] )
  • usage — The string describing the program usage (default: generated)

Learn more about argparse module

Exploring SQLite Module exploring-standard-modules-embedded-relational-database-module

SQLite is a C-language library that implements a SQL like database engine which is relatively quick, serverless and self-contained, high-reliable. SQLite comes built-in with most of the moden software, hardware devices and browsers, thus Python also has embedded SQLite engine named sqlite3.

To Start using the sqlite3 library:

Commonly used functions:

  • sqlite3.connect() — A connection object is created using the connect() function e.g connection = sqlite.connect(‘name_of_file_db.db’)
  • connection.cursor() — To execute SQLite statements, cursor object is needed. You can create it using the cursor() method. e.g cursor_object = connection.cursor()
  • connection.execute() — To create a table in SQLite3, you can use the Create Table, Insert Into Table, Update Table, or Select query with the execute() method of SQLite library. For example cursor_object.execute(«CREATE TABLE employees()»); connection.commit()
  • connection.commit() — The commit() method saves all the changes we make.
  • cursor_object.fetchall() — To fetch the data from a database we will execute the SELECT statement and then will use the fetchall() method of the cursor object to store the values into a variable, e.g cursor_object.execute(‘SELECT * FROM employees’) ; rows = cursor_object.fetchall()
  • cursor_object.rowcount() — The SQLite3 rowcount is used to return the number of rows that are affected or selected by the latest executed SQL query
  • cursor_object.executemany() — It can use the executemany statement to insert multiple rows at once.
  • connection.close() — You are done with your database, it is a good practice to close the connection with close() method. e.g. connection.close()

Learn More about SQLite3 Module

Exploring XmlTree Module exploring-xmltree-module

Learn More about XmlTree Module

Exploring JSON Module exploring-json-module

JSON is text, written with JavaScript object notation. JSON is a syntax for storing and exchanging data.
It is commonly used for transmitting data in web applications (e.g., sending some data from the server to the client, so it can be displayed on a web page
and vice versa

  • json.loads()
  • take a file object and returns the json object. A JSON object contains data in the form of key/value pair. The keys are strings and the values are the JSON types
  • json.dumps()
    -json.dumps() function converts a Python object into a json string
    .It is the exact opposite of json.loads.

THIS IS THE ENCODING DECODING LIST

1)object- DICT
2)array — list
3)string — str
4)int — int
5)real — float
6)true — true
7)False — False
8)NULL — NONE

  • Encoding is from python to JSON(final type)
  • Decoding is from JSON to python(final type)

Encoding functions

  • iterencode(o)
    -Encode the given object, o, and yield each string representation as available. For example:

for chunk in json.JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)]

-sort-keys -Sort the output of dictionaries alphabetically by key.

-h, —help¶ — help box

infile -to check your Json file for syntax

outfile -Write the output of the infile to the given outfile

Note

If the optional infile and outfile arguments are not specified, sys.stdin and sys.stdout will be used respectively:

json.tool — to validate and pretty-print JSON objects.

raw_decode — This can be used to decode a JSON document from a string that may have extraneous data at the end.

Learn More about JSON Module

Автор перевода messerr, просто с кармой ему не повезло.

Введение

Как системный администратор, вы сталкиваетесь с многочисленными проблемами. Управление пользователями, дисковым пространством, процессами, устройствами и бэкапами могут стать причиной потери волос, юмора или вменяемости у многих администраторов. Shell скрипты могут выручить, но они зачастую имеют множество ограничений. В этом случае полнофункциональный скриптовый язык, такой как Python, способен превратить утомительную задачу в легкую и, смею сказать, веселую.
Примеры в этой статье демонстрируют различные возможности Python, которые вы можете использовать на практике. Если Вы работаете с помощью них — вы на правильном пути к пониманию силы Python.

О модулях

Модуль – важное понятие в языке Python. По существу, модуль – это ресурс, который вы подключаете к программе, чтобы затем использовать его. Этот процесс можно сравнить с тем, что вы достанете из ящика лист бумаги и положите его на свой стол, подготовив тем самым к дальнейшему использованию. Модули подключаются при помощи команды import, которая присутствует в начале каждого примера. Модули доступны для связи с базами данных, сетевого программирования, сервисов операционных систем и сотен других полезных областей.

Заставим Python работать

Python — полнофункциональный, надежный язык программирования и, по существу, имеет массу свойств. Изучение его может стать задачей эпических масштабов. Однако, помните, что многие способности, такие как GUI инструментарий, имеют для системного администратора низкую ценность. Вот почему в этой статье используются специфичные примеры: они демонстрируют навыки, необходимые для эффективного написания скриптов управления системой.

Немного о примерах:

  • Каждый пример использует try: и except: с блоком кода внутри. Это осуществляет элементарную обработку ошибок. Python имеет обширную поддержку для обработки всех видов исключений, но, в рамках примеров этой статьи, я обошелся простой проверкой.
  • Эти примеры тестировались с помощью Python 2.5, запущенном на Linux® box, но они должны работать на любой Unix/Linux машине.

Вы несомненно задумаетесь об улучшении этих скриптов. Это хорошо! Натура Python-скриптов заключается в том, что они могут быть легко модифицированы и настроены без необходимости перекомпиляции.

Пример 1: Поиск файлов и отображение прав в дружественном формате

Первый пример (Листинг 1) осуществляет поиск файлов, в соответствии с шаблоном (который вводит пользователь) и выводит результат на экран вместе с правами доступа для каждого файла. Во-первых, вы можете подумать, что эта программа не делает ничего большего, чем вызов команды find; однако она отображает результаты особым образом и ваши варианты отображения этого расширенного поиска безграничны.
Скрипт по существу решает три задачи:

  1. Получает шаблон поиска от пользователя
  2. Выполняет поиск
  3. Показывает результаты пользователю

При написании скрипта постоянно задавайте себе вопрос, «Выполнение какой задачи данный код обеспечивает?» Задавая себе этот вопрос, вы повышаете внимание в вашей работе и ее эффективность.

Листинг 1. Поиск файлов и отображение результатов с правами доступа.

# -*- coding: utf-8 -*-
import stat, sys, os, string, commands
#Записываем в переменную шаблон поиска, введенный пользователем
try:
pattern = raw_input(«Введите шаблон поиска:n»)
#запускаем команду ‘find’ и присваиваем результат переменной
commandString = «find » + pattern
commandOutput = commands.getoutput(commandString)
findResults = string.split(commandOutput, «n»)
#выводим найденные файлы вместе с правами доступа
print «Файлы:»
print commandOutput
print «=============================== nPermissions for file «, file, «:»
for level in «USR», «GRP», «OTH»:
for perm in «R», «W», «X»:
if mode & getattr(stat,»S_I»+perm+level):
print level, » имеет «, perm, » права доступа»
else:
print level, » не имеет «, perm, » прав доступа»
except:
print «Возникла проблема! Проверьте сообщение выше.»

Программа следует по следующим этапам:

  1. Запрашивает у пользователя шаблон поиска (строки 7-9).
  2. Печатает список найденных файлов (строки 12-14).
  3. Используя модуль stat, получает права доступа для каждого найденного файла и отображает их на экране (строки 15-23).

Результат работы программы показан в Листинге 2.

$ python example1.py
Enter the file pattern to search for:
j*.py

Листинг 2. Вывод первого примера

$ python example1.py
Введите шаблон поиска:
j*.py
Файлы:
jim.py
jim2.py~
================================
Permissions for file jim.py :
USR имеет R права доступа
USR имеет W права доступа
USR не имеет X прав доступа
GRP имеет R права доступа
GRP не имеет W прав доступа
GRP не имеет X прав доступа
OTH имеет R права доступа
OTH не имеет W прав доступа
OTH не имеет X прав доступа
Permissions for file jim2.py :
USR имеет R права доступа
USR имеет W права доступа
USR не имеет X прав доступа
GRP имеет R права доступа
GRP не имеет W прав доступа
GRP не имеет X прав доступа
OTH имеет R права доступа
OTH не имеет W прав доступа
OTH не имеет X прав доступа

Пример 2: Выполнение операций с архивом tar при помощи меню

Предыдущий пример для своей работы запрашивал у пользователя поисковый шаблон. Другой способ получить от пользователя информацию — аргумент в командной строке. Программа в Листинге 3 показывает как сделать это в Python: код берет имя файла tar, как аргумент командной строки и затем предложит пользователю несколько опций. Этот пример так же показывает новый способ решения проблемы. Первый пример использовал модуль команд для запуска find и захвата вывода. Этот подход можно назвать неуклюжим и не очень «питоновским». Этот пример использует для открытия tar файла модуль tarfile, преимущество которого в том, что он позволяет Вам использовать атрибуты и методы Python при манипуляции с файлами. При помощи многих модулей Python, вы можете делать вещи, недоступные через командную строку. Этой хороший пример использования меню в Python. Программа выполняет различные действия в зависимости от вашего выбора:

  • Если вы нажмете 1, программа предложит выбрать файл в архиве для извлечения в текущую директорию и затем извлечет файл.
  • Если вы нажмете 2, программа предложит выбрать файл и затем покажет информацию о нем.
  • Если вы нажмете 3, программа выведет список всех файлов в архиве.

Листинг 3. Выполнение операций с архивом tar при помощи меню

# -*- coding: utf-8 -*-
import tarfile, sys
try:
#открываем tar-файл
tar = tarfile.open(sys.argv[1], «r:tar»)
#выводим меню и сохраняем выбор
selection = raw_input(«Введитеn
1 чтобы извлечь файлn
2 чтобы вывести информацию о файле в архивеn
3 чтобы показать все файлы в архивеnn»)
#выполняем действия, основанные на выборе
if selection == «1»:
filename = raw_input(«введите имя файла для извлечения: «)
tar.extract(filename)
elif selection == «2»:
filename = raw_input(«введите имя файла для просмотра: «)
for tarinfo in tar:
if tarinfo.name == filename:
print «n
Имя файла:tt», tarinfo.name, «n
Размер:tt», tarinfo.size, «байтn»
elif selection == «3»:
print tar.list(verbose=True)
except:
print «При выполнении программы возникла проблема!»

Программа следует по следующим этапам:

  1. Открывает tar файл (строка 5).
  2. Выводит на экран меню и получает выбор пользователя (строки 8-11).
  3. Если вы нажали 1 (строки 14-16), извлекает файл из архива.
  4. Если вы нажали 2 (строки 17-23), предоставляет информацию о выбранном файле.
  5. Если вы нажали 3 (строки 24-25), предоставляет информацию о всех файлах в архиве.

Результат работы программы показан в Листинге 4.

Листинг 4. Меню пользователя для второго примера

$ python example2.py jimstar.tar
Введите
1 чтобы извлечь файл
2 чтобы вывести информацию о файле в архиве
3 чтобы показать все файлы в архиве

Пример 3. Проверка запущенного процесса и отображение информации в дружественном представлении.

Одной из важнейших обязанностей системного администратора является проверка запущенных процессов. Скрипт в Листинге 5 даст вам несколько идей. Программа использует преимущества возможностей Unix: команда grep использует вывод, генерированный другой командой. Это позволит вам уменьшить объем данных, которые в дальнейшем будет анализировать Python.
Программа так же использует модуль string. Изучите этот модуль — вы будете часто его использовать.

Листинг 5. Отображение информации о запущенном процессе в дружественном представлении

# -*- coding: utf-8 -*-
import commands, os, string
program = raw_input(«Введите имя программы для проверки: «)
try:
#выполняем команду ‘ps’ и присваиваем результат списку
output = commands.getoutput(«ps -f|grep » + program)
proginfo = string.split(output)
#выводим результат
print «n
Путь:tt», proginfo[5], «n
Владелец:ttt», proginfo[0], «n
ID процесса:tt», proginfo[1], «n
ID родительского процесса:t», proginfo[2], «n
Время запуска:tt», proginfo[4]
except:
print «При выполнении программы возникла проблема!»

Программа следует по следующим этапам:

  1. Получает имя процесса для проверки и присваивает его переменной (строка 3).
  2. Запускает команду ps и добавляет результат в список (строки 7-8).
  3. Выводит детальную информацию о процессе (строки 11-16).
  4. Результат работы программы показан в Листинге 6.

Листинг 6. Вывод третьего примера

$ python example3.py
Введите имя программы для проверки: xterm
Путь: pts/0
Владелец: goga
ID процесса: 26509
ID родительского процесса: 26493
Время запуска: 17:28

Пример 4. Проверка имен пользователей и паролей на соблюдение политики безопасности. Управление безопасностью важная часть работы для каждого системного администратора. Python делает эту работу проще, как показывает последний пример. Программа в Листинге 7 использует модуль pwd для доступа к базе данных паролей. Она проверяет имена пользователей и пароли на соблюдение политики безопасности (в данном случае, имена должны быть как минимум 6 символов в длину, пароли — 8 символов). Есть два предостережения:
Эта программа работает только если у вас есть полные права для доступа к /etc/passwd.
Если вы используете теневые пароли, скрипт работать не будет (однако, в Питон 2.5 есть модуль spwd, который решит эту проблему).

Листинг 7. Проверка имен пользователей и паролей на соблюдение политики безопасности

# -*- coding: utf-8 -*-
import pwd
#заводим счетчики
erroruser = []
errorpass = []
#получаем базу данных паролей
passwd_db = pwd.getpwall()
try:
#проверяем каждое имя пользователя и пароль на валидность
for entry in passwd_db:
username = entry[0]
password = entry [1]
if len(username) < 6:
erroruser.append(username)
if len(password) < 8:
errorpass.append(username)
#выводим результаты на экран
print «Следующие пользователи имеют имена менее чем из 6 символов:»
for item in erroruser:
print item
print «nСледующие пользователи имеют пароли менее чем из 8 символов:»
for item in errorpass:
print item
except:
print «Возникла проблема при выполнении программы!»

Программа следует по следующим этапам:

  1. Инициализирует списки счетчиков (строки 4-5).
  2. Открывает базу данных паролей и записывает данные в список (строка 8).
  3. Проверяет имена пользователей и пароли на валидность (строки 12-18).
  4. Выводит имена и пароли, не соответствующие политике безопасности (строки 21-26).

Результат работы программы показан в Листинге 8.

Листинг 8. Вывод четвертого примера

$ python example4.py
Следующие пользователи имеют имена менее чем из 6 символов::
Guest
Следующие пользователи имеют пароли менее чем из 8 символов:
Guest
johnsmith
joewilson
suejones

Другое применение скриптов. Вы можете использовать Python по ряду направлений для управления системой. Одна из лучших вещей, которую вы можете сделать — проанализировать свою работу, определить какие задачи вы выполняете неоднократно и изучить модули Python, которые помогут вам решить эти задачи — почти наверняка, таковые найдутся. Некоторые области, где Python может быть отличным помощником:

  • Управление серверами: проверка патчей для конкретного приложения и их автоматическое обновление.
  • Журналирование: автоматическая отправка e-mail при появлении в логах особого вида ошибки.
  • Сеть: создание Telnet соединения к серверу и слежение за статусом соединения.

Тестирование web-приложений: использование свободно доступных инструментов для эмуляции веб-браузера и проверки веб-приложения на функциональность и производительность.
Это всего лишь несколько примеров — я уверен вы сможете добавить к ним свои собственные полезные идеи.

Резюме

С его легкостью в изучении, его умением управлять файлами, процессами, строками и числами, и его почти бесконечным массивом вспомогательных модулей, Python — это скриптовый язык, который выглядит так, будто был создан специально для системных администраторов. Python — это ценный инструмент в инструментарии любого системного администратора.

Python3 for Systems Administrator

Contents

Getting Started Standard Input, Output and Error

Standard input, output and error (commonly referred to as stdin , stdout and stderr ) are what’s called pipes.

These pipes are normally connected to the terminal window where you are working.

When printing something (using print() ), it goes to the stdout pipe by default; when your program needs to print errors (like a traceback in Python), it goes to the stderr pipe; and when your program requires input from a user or other programs, it goes to the stdin pipe.

$ cat /etc/passwd | grep /bin/bash # `_ writes to stdout `_ reads from stdin $ ls no_such_file.txt # `_ writes to stderr

Python built-in sys module provides stdin , stdout and stderr as a file-objects, exposing read() , readlines() , write() , writelines() methods, as shown below:

#!/usr/bin/env python3 import sys # writing to stdout pipe print ('Hello, world') sys.stdout.write('Hello, worldn') # writing to stderr pipe print("Error occured") sys.stderr.write("Error occuredn") # reading single line from stdin pipe sys.stdout.write('Username: ') username = sys.stdin.readline() print (username) # reading 'n' number of characters from stdin print ('Enter few characters and press Ctrl-D') data = sys.stdin.read(1024) print('len(data):', len(data)) # reading lines (separated by newlines) from stdin print('Enter few lines and press Ctrl-D') lines = sys.stdin.readlines() print ('total lines read:', len(lines))

Getting Started Working with files

Python built-in open function is the standard interface for working with files. open returns a file object with familiar methods for performing read/write operations.

Common arguments:
  • file: absolute or relative path of the file. e.g: /etc/passwd , ./ip-list.txt
  • mode: an optional string specifying mode in which the file is opened. Default’s to r for reading in text mode. Common values are:
  • w write only (truncates the file already exists)
  • x create and write to a new file (if file already exists then open fails)
  • a append to a file (insert data to end of the file)
  • + updating a file (reading and writing). e.g: r+ w+
  • b binary mode for non-text files. Contents are returned as byte objects.
  • t text mode (default). Contents are returned as strings .
File object methods:
  • .close()
  • .read(size=-1) read at most n characters. If n is negative or ommited, reads the whole file until EOF .
  • .readline() Read single line until newline or EOF .
  • .readlines() Read all newlines and returns as a list.
  • .write(data) Write data to file. Returns number of characters written.
  • .writelines(list) Write all data in the list. Useful for writing multiple lines to a file.
Example
## Reading a file r = open('/etc/passwd') # same as: # r = open('/etc/passwd', 'r') passwd = r.readlines() for line in passwd: line = line.strip() size = len(line) print(size, line) r.close() ## Reading a file using `with` statement, automatically closes the file with open('/etc/passwd') as f: pass ## Writing to a file w = open('test.txt', 'w') w.write('127.0.0.1n') w.flush() lines = ['1.1.1.1n', '2.2.2.2n', '3.3.3.3n'] w.writelines(lines) w.close()

Handling Errors

All open related errors raises IOError exception.

try: f = open('/etc/passwd') except IOError as e: print ('Opps, something went wrong.') print (e)

Reading /etc/passwd and search each line for /bin/bash shell; when found print the line number and the line

#!/usr/bin/env python3 # working-with-files-01.py def main(): try: with open('/etc/passwd') as f: for no, line in enumerate(f, 1): if '/bin/bash' in line: line = line.strip() print(f'no> line>') except IOError as e: print(e) if __name__ == '__main__': main()

Using fileinput High-level module

fileinput module allows to quickly write a loop over standard input or a list of files.

Example
#!/usr/bin/env python3 # linescount-02.py import fileinput lines = 0 for line in fileinput.input(): lines += 1 print('totat lines:', lines)
$ cat /etc/passwd | python3 linescount.py totat lines: 86 $ python3 linescount.py /etc/services totat lines: 13921 $ python3 linescount.py /etc/services /etc/passwd /etc/hosts totat lines: 14023

By default, fileinput.input() will read all lines from files given as an argument to the script; if no arguments given then defaults to standard input.

Getting Started Command-line Arguments

sys module provides argv variable containing the list of arguments passed to the script when executed as a command-line application.

NOTE: The first argument sys.argv[0] is always the name of the script itself.

#!/usr/bin/env python3 # argv_01.py import sys print ('sys.argv:', sys.argv) print ('length:', len(argv))
$ python3 args_01.py --help ['argv-01.py', '--help'] 2 $ python3 args_01.py 1 2 3 ['argv-01.py', '1', '2', '3'] 4

Accept specific number of arguments and fail if not satistified.

#!/usr/bin/env python3 # args-02.py import sys # NOTE: [1:] excludes the first item at index 0, i.e script name argv_len = len(sys.argv[1:]) if not argv_len == 2: sys.exit(f'invalid number of arguments (expected 2, given: argv_len>)') print('two arguments are:', sys.argv[1:])
$ python args_02.py invalid number of arguments (expected 2, given: 0) $ python args_02.py 1 invalid number of arguments (expected 2, given: 1) $ python args_02.py 1 2 two arguments are: ['1', '2'] $ python args_02.py 1 2 3 invalid number of arguments (expected 2, given: 3)

Simple Implementation of `grep’ command

#!/usr/bin/env python3 # grep.py import sys script = sys.argv[0] def print_usage(): sys.exit(f'Usage: python script> pattern') def main(argv): if not len(argv) == 1: print_usage() pattern = argv[0] for line in sys.stdin: if pattern in line: print(line.strip()) if __name__ == '__main__': main(sys.argv[1:])
$ cat /etc/services | python3 grep.py 8080 http-alt 8080/udp # HTTP Alternate (see port 80) http-alt 8080/tcp # HTTP Alternate (see port 80)

Improvement Exercises

  • Extend grep.py to read from a file instead of standard input, and can be run as:
$ python3 grep.py 8080 /etc/services
  • Extend grep.py to read from a file if given as a second argument or default back to read from standard input similar to what grep does.
$ cat /etc/services | python3 grep.py 8080 # and also should works as $ python3 grep.py 8080 /etc/services

Exploring Standard Modules Operating System (OS) Module

Python built-in os module exposes operating system dependent functionality in a portable way, thus works across many different platforms.

Working with environmental variables:
  • os.environ a dictionary mapping system environment variables. e.g. os.environ.get(‘SHELL’)
  • os.getenv(key) retrieve a specific variable.
  • os.putenv(key, value) . change variable to specific value. e.g. os.putenv(‘HOME’, ‘/opt’)
Working with files and directories:
  • os.tmpnam returns a unique file name that can be used to create temporariry file. mktemp() from tempfile module is more secure.
  • os.mkdir(path) os.rmdir(path) os.chdir(path) os.listdir(path)
  • os.getcwd() returns current working directory as string. Similar to pwd command.
  • os.stat(path) similar to stat command
  • os.walk(path) recursively walk the dictionary tree, similar to ls -R . Returns generator yielding 3-tuple (dirpath, dirnames, files)
Example
>>> import os # environment variables >>> os.environ['SHELL'] # or os.environ.get('SHELL') or os.getenv('SHELL') 'bash' # Get a temporary filename using `tempfile` module >>> from tempfile import mktemp >>> temp = mktemp() '/var/folders/6s/4xn2fv852_1ghssypng0wwfw0000gn/T/tmp15O9aR' # Create the temporary file and write 'test' >>> with open(temp, 'w') as f: . f.write('testn') # Get the file stat, such as creation timestamp (ctime) >>> st = os.stat(temp) >>> st.st_ctime 1436466688.0 # convert timestamp to human readable format, we'll cover date & time later. >>> import datetime >>> d = datetime.datetime.fromtimestamp(st.st_ctime) >>> d.year # d.month, d.hour and so on. 2016
Working with Path names os.path :
  • os.path.abspath(path) get absolute path.
  • os.path.basename(path) get the filename excluding the directory part. Opposite of os.path.dirname which excludes filename part and returns directory path.
  • os.path.exists(path) returns True if path exists else False .
  • os.path.getsize(path) return size (in bytes) for a given path.
  • os.path.isfile(path) , os.path.isdir(path) returns True or False if path is file or a directory.
  • os.path.getctime(path) , os.path.getmtime(path) Similar to os.stat(path).ctime , os.stat(path).mtime()

Learn more at os.path documentation

Example
>>> os.path.isdir('/etc') True >>> os.chdir('/etc') >>> os.getcwd() '/etc' >>> os.path.abspath('hosts') '/etc/hosts' >>> os.path.isfile('/etc/hosts') True >>> os.path.getsize('/etc/hosts') 475 >>> print (os.path.basename('/etc/passwd')) 'passwd' >>> print (os.path.dirname('/etc/passwd')) '/etc'
Process related functions:
  • os.getpid() get id of current process and os.getppid() to get parent process id.
  • os.system(command) execute a command and returns exit code.
Getting System Informations:
  • os.uname() returns a 5-tuple (sysname, nodename, release, version, machine) identifying the current OS. Similar to uname -a command.
  • os.getloadavg() returns 3-tuple containing 1-min, 5-min and 15-min load average.

Print size (in bytes) of all files in a given directory

#!/usr/bin/env python3 # filesizes.py import os import sys script = sys.argv[0] def print_usage(): print(f' >> sys.stderr>, "Usage: python3 script> DIR"') sys.exit(1) def filesizes(path): ''' calculate and print size of each file in a given directory. ''' for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: filepath = os.path.join(dirpath, filename) _bytes = os.path.getsize(filepath) print (f'_bytes>, filepath>') def main(argv): if not len(argv) == 1: print_usage() path = argv[0] filesizes(path) if __name__ == '__main__': main(sys.argv[1:])
$ python3 filesizes.py . 678 ./filesizes.py ``` 

Learn more about OS module

Exploring Standard Modules System-specific Module

Python built-in sys module exposes system-specific parameters and functions. This module provides access to some variables used or maintained by the interpreter and functions that interact strongly with the interpreter. sys module is always available.

Commonly used variables and functions:
  • sys.argv contains list of command-line arguments. Already covered.
  • sys.exit([arg]) exit the program. arg is optional, can be 0 to indicate success, > 0 for failure or string to display the errors during exit.
  • sys.version stores version of Python installed.
  • sys.stdin sys.stdout sys.stderr File objects corresponding to the interpreter’s standard input, output and error pipes.
  • sys.platform stored the name of the platofrm Python is running. Such as darwin for MacOS, linux for Linux and others
  • sys.path A list of strings that specified the search path while importing modules via import statement.
  • sys.modules A dictionary mapping the < 'module_name': 'module_path', . >which have already been loaded.
#!/usr/bin/env python3 # sys-01.py import sys from sys import argv print (f''' Python version installed: sys.version> Python running on platforn: sys.platform> ''') if len(argv) == 10: sys.exit('error: too many arguments') print(f''' argv = argv> len(argv) = len(argv)> ''') print ('Printing to stdout') print (f'>> sys.stderr>, "Printing to stderr"') print(f''' total modules search path: len(sys.path)> total modules loaded: len(sys.modules)> ''') # success sys.exit(0)
Output should look like this
$ python3 sys-01.py Python version installed: 3.7.4 (default, Jul 9 2019, 16:48:28) [GCC 8.3.1 20190223 (Red Hat 8.3.1-2)] Python running on platforn: linux argv = ['sys_01.py'] len(argv) = 1 Printing to stdout >> _io.TextIOWrapper name='' mode='w' encoding='UTF-8'>, "Printing to stderr" total modules search path: 7 total modules loaded: 57 $ echo $? 0

Learn more about sys module

Exploring Standard Modules Shell Modules

shutil module — High-level file operations

The shutil module provides high-level operations on files or collection of files.

Copy Operations:
  • shutil.copy(src, dst) Copy src file to dst file or directory.
  • shutil.copymode(src, dst) Copy permission mode of src file to dst file.
  • shutil.copystat(src, dst) Copy permission mode, modification and creation date from src file to dst file.
  • shutil.copy2(src, dst) Similar to cp -p command or equivalent of shutil.copy and shutil.copystat .
Move Operations:
  • shutil.move(src, dst) Move src file to dst file or directory.

Learn more about shutil module

glob module — Unix style pathname pattern expansion

The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell.

  • glob.glob(pattern) Return a list of path names that match the path pattern. Path can be absolute /usr/local/bin/*.py or relative local/bin/*.py .
Example
>>> import glob >>> glob.glob('/etc/sysconfig/network-scripts/ifcfg*') ['/etc/sysconfig/network-scripts/ifcfg-venet0', '/etc/sysconfig/network-scripts/ifcfg-lo'] >>> glob.glob('/etc/*.conf') ['/etc/vnstat.conf', '/etc/sudo.conf', '/etc/resolv.conf', '/etc/host.conf', '/etc/logrotate.conf']

Learn more about glob module

Exploring Standard Modules Date and Time Modules

time module — Clock time

The time module exposes the time-related functions from the underlying C library.

Commonly used functions:
  • time.time() returns the number of seconds since the start of the epoch as a floating-point value.
  • time.ctime() returns a human-friendly date and time representation.
  • time.gmtime() returns an object containing current time in UTC format.
  • time.localtime() returns an object containing the current time in current time zone.
  • time.tzset() sets the time zone based on TZ environment variable: os.environ.get(‘TZ’)
Example
>>> import time >>> time.time() 1459924583.396017 >>> # current time in UTC >>> utc = time.gmtime() >>> dir(utc) ['tm_hour', 'tm_isdst', 'tm_mday', 'tm_min', 'tm_mon', 'tm_sec', 'tm_wday', 'tm_yday', 'tm_year'] >>> # current time in GMT by updating timezone >>> import os >>> os.putenv('TZ', 'GMT') # or os.environ['TZ'] = 'GMT' >>> time.tzset() >>> gmt = '<> <>'.format(time.ctime(), time.tzname[0])

Learn more about time module

datetime module — Date and Time Value Manipulation

The datetime module includes functions and classes for doing date and time parsing, formatting, and arithmetic.

Commonly used functions:
  • datetime.date.today() returns current date object without the time
  • datetime.datetime.today() returns current date and time object
  • datetime.datetime.fromtimestamp(float) convert unix timestamp to datetime object
  • datetime.timedelta future and past dates can be calculated using basic arithmetic (+, -) on two datetime objects, or by combining a datetime with a timedelta object.
Example
>>> import datetime >>> today_date = datetime.date.today() >>> ten_days = datetime.timedelta(days=10) >>> today_date - ten_days # past >>> today_date + ten_days # future
Alternate formats can be generated using strftime() and strptime to convert formatted string to datetime object.
>>> import datetime # convert datetime to custom format >>> format = "%a %b %d %H:%M:%S %Y" >>> today = datetime.datetime.today() >>> today.strftime(format) 'Mon Oct 14 17:56:24 2019' # convert formatted string to datetime object >>> datetime.datetime.strptime('Mon Oct 14 17:56:24 2019', format) datetime.datetime(2019, 10, 14, 17, 56, 24)

Learn more about datetime module

Exploring Standard Modules Subprocess Module

subprocess module — Subprocess management

The subprocess module allows to run new processes, connect to their input/output/error pipes, and obtain their return codes.

The module defines a many helper functions and a class called Popen which allows to set up the new process so the parent can communicate with it via pipes.

Running external commands

To run an external command without interacting with, use subprocess.call(command, shell=True) function.

>>> import subprocess >>> rc = subprocess.call('ls -l /etc', shell=True) 0 >>> rc = subprocess.call('ls -l no_such_file.txt', shell=True) 1

Setting the shell argument to a True value causes subprocess to spawn a shell process (normally bash), which then runs the command. Using a shell means that variables, glob patterns, and other special shell features in the command string are processed before the command is run.

>>> import subprocess >>> subprocess.call('echo $PATH' ) # will return error subprocess.call('echo $PATH', shell=True) # will print the shell PATH variable value

Error Handling

The return value from subprocess.call() is the exit code of the program and is used to detect errors. The subprocess.check_call() function works like call() , except that the exit code is checked, and if it returns non-zero, then a subprocess.CalledProcessError exception is raised.

#!/usr/bin/env python3 # check_call.py import sys import subprocess try: cmd = 'false' print ('running command:',cmd) subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as error: sys.exit(f'error: error>')
$ python3 check_call.py running command: false error: Command 'false' returned non-zero exit status 1

Capturing Command Output

To run an external command and capture it’s output, use check_output(command, shell=True) to capture the output for later processing. If command returns non-zero, then a CalledProcessError exception is raised similar to check_call .

Execute cat /etc/hosts and write the output to a file hosts.txt

#!/usr/bin/env python3 # capture_output.py import subprocess import sys try: cmd = 'cat /etc/hosts' print('running command:', cmd) output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as error: sys.exit('error: ') else: print('success!') with open('hosts.txt', 'w') as f: f.write(output) #this should give an error in python3.6+

By default, check_output captures outputs written to stdout . Setting the stderr=subprocess.STDOUT causes stderr outputs to redirected to stdout , so errors can be captured as well.

Working directory with Popen

The call() , check_call() , and check_output() are wrappers around the Popen class. Using Popen directly gives more control over how the command is run and how its input and output streams are processed.

One-Way Communication with a Process

To run a process and capture it’s output, set the stdout and stderr arguments to subprocess.PIPE and call communicate() .

communicate() returns 2-tuple (stderr_output, stderr_putput)

#!/usr/bin/env python3 # one-way.py import subprocess import sys script = sys.argv[0] def main(argv): if not len(argv) == 1: sys.exit(f'usage: python3 script> command') cmd = sys.argv[1] print ('running command:', cmd) proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() print(f''' exit code: proc.poll()> stdout: stdout or None> stderr: stderr or None> ''') if __name__ == '__main__': main(sys.argv[1:])
$ python3 one_way.py ls running command: ls exit code: 0 stdout: b'capture_output.pyncheck_call.pynhosts.txtnone_way.pynsys_01.pyn' stderr: None

Bidirectional Communication with a Process

To set up the Popen instance for reading and writing at the same time, pass additional argument stdin=subprocess.PIPE .

#!/usr/bin/env python3 # bidirectional.py import subprocess from subprocess import PIPE import sys cmd = 'bc' send = '1 + 1n' print('running command:', cmd, 'and sending input:', send) proc = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = proc.communicate(send) print(f''' exit code: proc.poll()> stdin: send> stdout: stdout or None> stderr: stderr or None> ''')
$ python3 bidirectional.py running command: bc and sending input: 1 + 1 exit code: 0 stdin: 1 + 1 stdout: 2 stderr: None

Learn more about subprocess module

Exploring Argparse Command-Line Option and Argument Parsing

Python built-in argparse is parser for command-line options, arguments and subcommands. The argparse module provides argument management just like sys.argv , but with options, e.g it generates help and usage messages and issues errors when users give the program invalid arguments.
Let’s show the sort of functionality by making use of the ls command:

$ ls examples LICENSE README.md $ ls -l total 44 drwxrwxr-x. 4 que que 4096 Oct 14 18:05 . drwxrwxr-x. 24 que que 4096 Oct 13 15:32 .. drwxrwxr-x. 2 que que 4096 Oct 14 18:48 examples drwxrwxr-x. 8 que que 4096 Oct 15 01:01 .git -rw-rw-r--. 1 que que 1210 Oct 13 15:32 LICENSE -rw-rw-r--. 1 que que 24357 Oct 15 01:02 README.md $ ls --help Usage: ls [OPTION]. [FILE]. List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. .

A few concepts we can learn from the four commands:

  • When you run the «ls -l» command with options, it will default displaying the contents of the current directory
  • The «-l» is knowns as an «optional argument»
  • If you want to display the help text of the ls command, you would type «ls —help»

To start using the argparse module, we first have to import it.

Intro to positional arguments

The following code is a Python program that takes a list of integers and produces either the sum or the max:

Example
#!/usr/bin/env python3 #app.py import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') args = parser.parse_args() print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called app.py , it can be run at the command line and provides useful help messages

$ app.py -h usage: prog.py [-h] [--sum] N [N . ] Process some integers. positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) $ app.py 1 2 3 4 4 $ app.py 1 2 3 4 --sum 10

Creating a parser

The first step in using the argparse is creating an ArgumentParser object:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

The ArgumentParser object will hold all the information necessary to parse the command line into python data types.

Adding arguments

Filling an ArgumentParser with information about program arguments is done by making calls to the ArgumentParser.add_argument method. Generally, these calls tell the ArgumentParser how to take the strings on the command line and turn them into objects. This information is stored and used when ArgumentParser.parse_args is called. For example:

>>> parser.add_argument('integers', metavar='N', type=int, nargs='+', . help='an integer for the accumulator') >>> parser.add_argument('--sum', dest='accumulate', action='store_const', . const=sum, default=max, . help='sum the integers (default: find the max)')

Later, calling parse_args will return an object with two attributes, integers and accumulate. The integers attribute will be a list of one or more ints, and the accumulate attribute will be either the sum function, if —sum was specified at the command line, or the max function if it was not.

Parsing arguments

ArgumentParser parses args through the ArgumentParser.parse_args method. This will inspect the command-line, convert each arg to the appropriate type and then invoke the appropriate action. In most cases, this means a simple namespace object will be built up from attributes parsed out of the command-line:

>>> parser.parse_args(['--sum', '7', '-1', '42']) Namespace(accumulate=built-in function sum>, integers=[7, -1, 42])

In a script, ArgumentParser.parse_args will typically be called with no arguments, and the ArgumentParser will automatically determine the command-line args from sys.argv .

ArgumentParser objects

Create a new ArgumentParser object. Each parameter has its own more detailed description below, but in short they are:

  • description — Text to display before the argument help.
  • epilog — Text to display after the argument help.
  • add_help — Add a -h/—help option to the parser. (default: True)
  • argument_default — Set the global default value for arguments. (default: None)
  • parents — A list of ArgumentParser objects whose arguments should also be included.
  • prefix_chars — The set of characters that prefix optional arguments. (default: ‘-‘)
  • fromfile_prefix_chars — The set of characters that prefix files from which additional arguments should be read. (default: None)
  • formatter_class — A class for customizing the help output.
  • conflict_handler — Usually unnecessary, defines strategy for resolving conflicting optionals.
  • prog — The name of the program (default: sys.argv[0] )
  • usage — The string describing the program usage (default: generated)

Learn more about argparse module

Exploring SQLite Module exploring-standard-modules-embedded-relational-database-module

SQLite is a C-language library that implements a SQL like database engine which is relatively quick, serverless and self-contained, high-reliable. SQLite comes built-in with most of the moden software, hardware devices and browsers, thus Python also has embedded SQLite engine named sqlite3.

To Start using the sqlite3 library:

Commonly used functions:

  • sqlite3.connect() — A connection object is created using the connect() function e.g connection = sqlite.connect(‘name_of_file_db.db’)
  • connection.cursor() — To execute SQLite statements, cursor object is needed. You can create it using the cursor() method. e.g cursor_object = connection.cursor()
  • connection.execute() — To create a table in SQLite3, you can use the Create Table, Insert Into Table, Update Table, or Select query with the execute() method of SQLite library. For example cursor_object.execute(«CREATE TABLE employees()»); connection.commit()
  • connection.commit() — The commit() method saves all the changes we make.
  • cursor_object.fetchall() — To fetch the data from a database we will execute the SELECT statement and then will use the fetchall() method of the cursor object to store the values into a variable, e.g cursor_object.execute(‘SELECT * FROM employees’) ; rows = cursor_object.fetchall()
  • cursor_object.rowcount() — The SQLite3 rowcount is used to return the number of rows that are affected or selected by the latest executed SQL query
  • cursor_object.executemany() — It can use the executemany statement to insert multiple rows at once.
  • connection.close() — You are done with your database, it is a good practice to close the connection with close() method. e.g. connection.close()

Learn More about SQLite3 Module

Exploring XmlTree Module exploring-xmltree-module

Learn More about XmlTree Module

Exploring JSON Module exploring-json-module

JSON is text, written with JavaScript object notation. JSON is a syntax for storing and exchanging data.
It is commonly used for transmitting data in web applications (e.g., sending some data from the server to the client, so it can be displayed on a web page
and vice versa

  • json.loads()
  • take a file object and returns the json object. A JSON object contains data in the form of key/value pair. The keys are strings and the values are the JSON types
  • json.dumps()
    -json.dumps() function converts a Python object into a json string
    .It is the exact opposite of json.loads.

THIS IS THE ENCODING DECODING LIST

1)object- DICT
2)array — list
3)string — str
4)int — int
5)real — float
6)true — true
7)False — False
8)NULL — NONE

  • Encoding is from python to JSON(final type)
  • Decoding is from JSON to python(final type)

Encoding functions

  • iterencode(o)
    -Encode the given object, o, and yield each string representation as available. For example:

for chunk in json.JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)]

-sort-keys -Sort the output of dictionaries alphabetically by key.

-h, —help¶ — help box

infile -to check your Json file for syntax

outfile -Write the output of the infile to the given outfile

Note

If the optional infile and outfile arguments are not specified, sys.stdin and sys.stdout will be used respectively:

json.tool — to validate and pretty-print JSON objects.

raw_decode — This can be used to decode a JSON document from a string that may have extraneous data at the end.

Learn More about JSON Module

РОМАН ЗУСИ

Python в администрировании сервера: почему бы и нет?

Стандартных решений не существует. Каждый системный администратор рано или поздно начинает писать свои скрипты, которые облегчают его работу, избавляя от рутины. Для автоматизации в UNIX-системах традиционно применяются командные оболочки (типа bash или ksh, разновидностей оболочек достаточно много) и язык Perl. Причем, следуя философии UNIX, эти оболочки используют для решения проблемы целый набор инструментов, выполняющих небольшие частные задачи: ls, wc, sort, grep, diff, tar, …

Обычно простые задачи выполняются в командной оболочке запуcком соответствующих инструментов и организацией потока данных. Для более сложных задач требуются и более сложные инструменты, например, awk, sed или даже Perl. Так принято.

Однако хотелось бы обратить внимание системных администраторов на такой сценарный (скриптовый) язык как Python. Этот язык, благодаря своим хорошим качествам, о которых поговорим далее, уверенно завоевывает популярность, в том числе для задач системного администрирования. Например, именно его применяет Red Hat в инструменте под названием anaconda для обеспечения начальной установки своего дистрибутива Linux.

Конечно, системные администраторы – натуры весьма консервативные, и потому я решил написать эту статью, показывающую, что Python действительно имеет преимущества по сравнению с языком Perl и оболочками при решении как повседневных, так и одноразовых задач.

Python – интерпретируемый язык с развитыми высокоуровневыми структурами данных, имеющий все необходимое для вызова функций POSIX-совместимых систем. Впрочем, Python является многоплатформенным языком, так что его можно с успехом использовать и, к примеру, в среде Windows. Однако не буду долго говорить о происхождении и синтаксисе языка: об этом заинтересованный читатель узнает на http://python.ru или из книги Сузи Р.А. Python. – СПб.: БХВ-Петербург, 2002; а сразу перейду к делу.

Начнем с небольшого примера, в котором нам требуется установить права и принадлежность файлов, чтобы имена совпадали с именами пользователей в системе (для простоты будем считать, что имена пользователей доступны из файла /etc/passwd). Подобная задача может возникнуть, например, в каталоге с почтовыми ящиками, где каждый ящик должен принадлежать соответствующему его названию пользователю.

import os, string

for line in open(«/etc/passwd»).readlines():

users[rec[0]] = int(rec[2]), int(rec[3]) # uid и gid

for file in os.listdir(«.»):

uid, gid = users[file]

print «Сирота: «, file

uid, gid = 0, 0 # root

os.chown(file, uid, gid)

В самом начале мы импортируем модуль для работы с функциями ОС (os) и работы со строками (string). Перед началом цикла по строкам файла /etc/passwd словарь users пуст. В цикле по строкам файла /etc/passwd мы делаем следующее. Именем rec обозначаем кортеж значений записи passwd-файла. Мы знаем, что первое поле этой записи – имя пользователя. Имя пользователя и станет ключом в словаре users. В качестве значения для данного ключа мы берем приведенные к целому типу поля 2 и 3, соответствующие идентификаторам пользователя и группы. Таким образом в первом цикле формируется отображение имени пользователя и его идентификаторов. Во втором цикле, по именам файлов в текущем каталоге, пытаемся (try) найти владельца файла, обращаясь к словарю users. Если это не удается, мы пишем на стандартный вывод соответствующую диагностику. В этом случае владельцем файла станет root. Последние две команды, думается, ясны и без комментариев.

В приведенном на листинге примере были использованы очевидные решения, не требующие особого знания стандартной библиотеки Python.

Для любознательных укажем и второй путь решения, в котором используются «правильные» средства:

import os, pwd, glob

for file in glob.glob(«*»):

print «Сирота: «, file

os.chown(file, rec[2], rec[3])

Здесь удалось добиться некоторого сокращения программы за счет использования функции getpwnam модуля pwd стандартной библиотеки Python. Здесь также применена функция glob из одноименного модуля для получения списка файлов.

Для сравнения приведен неправильный пример подобной же программы, написанный в оболочке bash.

# Не работает, если имена файлов содержат точку или пробел

chown $file.$file $file || chown root.root $file

Конечно, на языке командной оболочки программа получилась раза в два короче. Однако в ней таится неприятная неожиданность: она работает некорректно для файлов, содержащих в имени точку, пробел или дефис в начале!

Я более чем уверен, что программу можно переписать, экранировав символы должным образом. Но тем не менее, зная Python, можно быстрее написать скрипт, решающий ту же задачу без скользких текстовых подстановок.

Из приведенных примеров уже видна особенность языка Python, не всеми воспринимаемая хорошо: для выделения фрагментов кода в составных операторах используется единообразный отступ. Тем самым интерпретатор Python требует от программиста визуально выделять структуру программы, что положительно сказывается на читаемости кода. И это немаловажно, ведь написанный скрипт может пригодиться для похожей задачи.

В следующем примере мы рассмотрим еще одну часто возникающую задачу: проверка работоспособности POP3-сервиса и отправка сообщения электронной почты в случае неудачи. Заметьте, что приведенный пример одинаково хорошо подходит и для UNIX, и для NT.

import smtplib, poplib

Subject: POP3 down.

Please, restart pop3 at mymail.

print «нет связи»

С помощью конструктора объекта POP3-соединения из модуля poplib мы пытаемся установить соединение с POP3-сервером mymail. Если это не удается, мы должны отправить о происшествии письмо на admin@othermail. В этом нам поможет модуль smtplib и конструктор класса SMTP. Если и это не удается, просто выводится «нет связи». Заметьте, как легко в Python ввести многострочный текст.

Надеемся, вы как минимум заинтересовались предлагаемым инструментом.

Таблица 1 поможет быстро найти аналоги распространенных команд среди функций стандартной библиотеки языка Python. Перед использованием функции достаточно импортировать соответствующий модуль.

chmod режим путь

chown uid.gid путь

os.chown(« путь «, uid, gid)

time.localtime(time.time()) и другие функции модуля time

функции модуля difflib

print «%(перем)s» % vars()

для работы с регулярными выражениями служит модуль re

ln -s путь1 путь2

help(«тема») или help(объект)

socket.gethostbyname(«хост») и другие функции этого модуля

os.unlink(«файл») или os.remove(«файл»)

модули httplib, urllib, urllib2, urlparse

f = os.popen(«команда», «r»)

f = os.popen(«команда», «w»)

f = open(« файл «, «r»); f.read(); f.close()

f = open(« файл «, «r»); f.write(…); f.close()

Настало время разобрать более сложный пример – программу для анализа логов почтового сервера Sendmail. Наверное, не нужно долго объяснять, что для обеспечения бесперебойной работы сервера и требуемого качества обслуживания просто необходимо вовремя выявлять аномалии в его работе и пресекать попытки злоупотребления сервисом. Одна из основных проблем – массовые несанкционированные рассылки, или попросту спам. И проблема эта не только в том, чтобы уберечь пользователей сервера от спама, но и вовремя заметить попытки применения пользователями программ массовой рассылки.

Я почти уверен, что на рынке имеются готовые инструменты для решения этой проблемы. Даже очень возможно, что нужные программы есть в свободном распространении. Однако простые средства во многих случаях можно написать и самому, руководствуясь своим опытом и, возможно, знанием местной специфики. Тем более, что это не требует много времени.

Разбираемый ниже пример не претендует на полноту решения проблемы спама, он решает частную задачу. Мы будем отслеживать лишь попытки массовых рассылок, в которых на один «mail from» следуют несколько «rcpt to». Конечно, программу легко адаптировать и для другой ситуации, агрегируя данные по отправителям, получателям и так далее, получая портрет ситуации на почтовом сервере. Следует заметить, что глядя на «сырые» логи Sendmail не всегда можно увидеть проблему. Во всяком случае, для этого требуется некоторое напряжение глаз.

Наша небольшая программа на Python будет собирать данные о сеансах и показывать только сеансы с большим числом получателей. В логе эта информация сильно размазана, поэтому простого применения инструмента вроде grep здесь оказывается недостаточно.

Накапливаемые данные мы будем сохранять в файлах-хэшах (аналогичных тем, в которых хранятся, например, псевдонимы), благо в Python есть для этого нужные модули. (Конечно, в Python можно использовать и полновесные базы данных с языком запросов SQL, однако это непринципиально).

Задача распадается на две: сбор данных из лога в базу данных и выборка из базы данных.

«»»Анализ лога Sendmail»»»

import os, re, sys, anydbm, time

server_name = «mail» # имя сервера, фигурирующее в логах

try: os.unlink(file) # удаляем старую БД

except: pass # игнорируем исключения

return anydbm.open(file, «c»)

f = createdb(«from.db») # ид сессии: отправитель

t = createdb(«to.db») # ид сессии: получатели

r = createdb(«relay.db») # ид сессии: почтовый хост

d = createdb(«date.db») # время и ид сессии: ид сессии

»’ Примеры четырех характерных случаев:

Aug 11 20:24:25 mail sendmail[4720]: g7BGOHY2004720: from=, size=103655, nrcpts=1, msgid=, proto=SMTP, daemon=MTA, relay=[212.28.127.12]

Aug 11 20:24:25 mail sendmail[4720]: g7BGOHY2004720: to=, delay=00:00:07, pri=133655, stat=Headers too large (32768 max)»’

Aug 11 04:02:31 mail sendmail[17058]: g7B02UY2017058: from=, size=33977, nrcpts=1, msgid=, proto=SMTP, daemon=MTA, relay=relay1.aport.ru [194.67.18.127]

Aug 11 07:18:20 mail sendmail[28329]: g7B3ICY2028329: … User unknown»’

# характерные части регулярных выражений (префикс, хост и адрес)

# регулярные выражения, соответствующие разным случаям

log3_re = re.compile(r»%(P)s(?Pfrom)=%(A)s, .*, %(R)s» % vars())

log4_re = re.compile(r»%(P)s%(A)s… (?PUser unknown)» % vars())

input_file = open(sys.argv[1], «r») # открываем файл с логом

if not line: # обнаружен конец файла: выход из цикла

# сравниваем строку лога с шаблонами

m = log1_re.match(line) or log2_re.match(line) or log3_re.match(line) or log4_re.match(line)

if m: # если хоть один шаблон сработал:

found = m.groupdict() # получаем словарь групп результата

date, session_id, addr = found[«date»], found[«session»], found[«addr»]

direc = found.get(«direc», «to») # по умолчанию «to»

stat = found.get(«stat», «») # по умолчанию — пустая строка

if direc == «to» and stat[:4] != «Sent» and stat != «User unknown»:

continue # такие сообщения не интересуют

if direc == «to»: # в зависимости от направления

t[session_id] = t[session_id] + addr + «;»

r[session_id] = found.get(«relay_ip», «») or found.get(«relay», «»)

d[date + session_id] = session_id

f.close(); t.close(); r.close(); d.close()

Построчно читаем из файла с логами и, в зависимости от сработавшего шаблона, записываем в заранее открытые базы данных. Обратите внимание, что база date.db использует в качестве ключей как дату, так и идентификатор сессии. Последний делает ключ уникальным.

Заметим, что в Python логические операции or и and работают несколько необычно. Любой объект имеет так называемое истинностное значение. Нули, пустые последовательности, объект None считаются «ложью», а остальные объекты – истиной. В результате операции A or B возвращается объект A, если он «истинен», а в противном случае – объект B. Именно поэтому имени m будет соответствовать результат первого успешного сравнения.

Python оперирует такими высокоуровневыми объектами, как список и словарь. Словарь задает отображение между ключами и значениями. В частности, found является словарем, отображающим имя найденной в строке лога группы и значения этой группы. Имена групп в регулярных выражениях задаются через (?P …). Взять из словаря значение по ключу можно не только с помощью словарь[ключ], но и с помощью метода get(). В последнем случае можно задать значение «по умолчанию», то есть значение, которое метод get() возвратит в случае отсутствия ключа в словаре.

Стоит заметить, что работа с базами данных использует тот же синтаксис, что и работа со словарями (об этом позаботились разработчики модуля anydbm).

Итак, мы поместили информацию из лога Sendmail в более удобный для обработки вид – в базы данных (хэши). Следующая программа — пример одного из обработчиков, которые мы теперь можем применить.

Для нашей цели (выявление чрезмерных списков рассылки) данные удобно отсортировать по времени. Это легко сделать с ключами из базы date.db. По сути мы считываем все ключи этой базы в память (метод keys()) и сортируем их по возрастанию.

«»»Анализируем собранные данные»»»

import re, sys, anydbm, string

f = anydbm.open(«from.db», «r»)

t = anydbm.open(«to.db», «r»)

r = anydbm.open(«relay.db», «r»)

d = anydbm.open(«date.db», «r»)

# показывать только случаи отправления >= LIM получателям

dkeys = d.keys() # получаем все ключи в один список

# сортируем (фактически, по времени). Пренебрегаем сменой месяцев

«»»Функция для фильтрации получателей»»»

for date_sess_id in dkeys:

i = d[date_sess_id] # находим идентификатор сессии

recps = string.split(t[i], «;») # список получателей

# берем только адреса с @

recps = filter(our_filter, recps)

sender = f[i] # отправитель

if len(recps) >= LIM and not good_guys_re.match(sender):

dte = date_sess_id[:15] # первые 15 символов — дата

print f[i], relay, dte, «->n «, string.join(recps, «n «)

except: # если возникли ошибки, пропускаем

f.close(); t.close(); r.close()

Здесь особо следует отметить функцию filter(). Эта встроенная функция применяет некоторую функцию (аргумент 1) к списку (аргумент 2). В нашем случае используется our_filter, которая возвращает «истину» в случае, когда ее аргумент содержит «@».

Составленная программа далека от совершенства, однако ее легко доработать в любом нужном направлении: добавить возможность обработки нескольких файлов логов сразу; обрабатывать ситуации, когда несколько получателей указаны в одной строке лога; изменить правила фильтрации, изменить способ агрегирования данных (например, агрегировать по именам получателей, именам отправителей, адресам почтовых хостов); сделать из программы демона, непрерывно следящего за логами и т.п.

Составляя наши программы, мы выразили логику анализа логов почтового сервера и почти не отвлекались на обдумывание применяемых конструкций языка программирования и конструирование типов данных.

Программисты на Python утверждают, что на этом языке можно писать «со скоростью мысли», то есть, почти все время оставаясь в предметной области. Если вы этому не верите, попробуйте переписать приведенные программы с использованием стандартного Си или Java. С другой стороны, приведенную задачу обычно решают с помощью языка Perl. К сожалению, Perl вносит очень много синтаксического мусора, что подчас значительно затеняет логику программы.

Основными преимуществами Python являются, на мой взгляд:

  • удобный и легко читаемый синтаксис;
  • многоплатформенность;
  • поддержка основных системных и сетевых протоколов и форматов;
  • большой набор библиотек;
  • свободное распространение;
  • дружелюбная поддержка в телеконференции comp.lang.python;
  • надежный и устойчивый интерпретатор.

Все это делает Python отличным инструментом в работе системного администратора.

Название книги: Python в системном администрировании UNIX и Linux
Год: 2009
Авторы: Ноа Гифт, Джереми М. Джонс
Язык: Русский
Формат: djvu, fb2, epub, mobi
Размер: 6.4 МВ, 1 MB, 0.5 MB, 0.6 MB

Книга «Python в системном администрировании UNIX и Linux» демонстрирует, как эффективно решать разнообразные задачи управления серверами UNIX и Linux с помощью языка программирования Python. Каждая глава посвящена определенной задаче, например многозадачности, резервному копированию данных или созданию собственных инструментов командной строки, и предлагает практические методы ее решения на языке Python.

Среди рассматриваемых тем: организация ветвления процессов и передача информации между ними с использованием сетевых механизмов, создание интерактивных утилит с графическим интерфейсом, организация взаимодействия с базами данных и создание приложений для Google App Engine.

Для кого эта книга

Издание рассчитано на широкий круг специалистов — всех, кто только начинает осваивать язык Python, будь то опытные разработчики сценариев на языках командной оболочки или относительно мало знакомы с программированием вообще.

Оглавление:

Глава 1: Введение

Глава 2: IPython

Глава 3: Текст

Глава 4: Создание документации и отчетов

Глава 5: Сети

Глава 6: Данные

Глава 7: SNMP

Глава 8: Окрошка из операционных систем

Глава 9: Управление пакетами

Глава 10: Процессы и многозадачность

Глава 11: Создание графического интерфейса

Глава 12: Сохранность данных

Глава 13: Командная строка

Глава 14: Практические примеры

Скачать: «Python в системном администрировании UNIX и Linux»

Python системном администрировании unix linux

Библиотека программиста запись закреплена

Гифт Н., Джонс Дж.М. «Python в системном администрировании UNIX и Linux» (pdf) #python

Книга «Python в системном администрировании UNIX и Linux» демонстрирует, как эффективно решать разнообразные задачи управления серверами UNIX и Linux с помощью языка программирования Python. Каждая глава посвящена определенной задаче, например многозадачности, резервному копированию данных или созданию собственных инструментов командной строки, и предлагает практические методы ее решения на языке Python.

Среди рассматриваемых тем: организация ветвления процессов и передача информации между ними с использованием сетевых механизмов, создание интерактивных утилит с графическим интерфейсом, организация взаимодействия с базами данных и создание приложений для Google App Engine. Кроме того, авторы книги создали доступную для загрузки и свободно распространяемую виртуальную машину на базе Ubuntu, включающую исходные тексты примеров из книги и способную выполнять примеры, использующие SNMP, IPython, SQLAlchemy и многие другие утилиты.

Совсем не много компьютерных книг способны оставаться актуальными хотя бы 2 года. Думаю, что эта книга будет жить значительно дольше. Книга написана не техническим писателем, а работающим системным администратором для системных администраторов. При чтении складывается ощущение, что это просто расширенный и обработанный вариант внутренне документации. Рекомендую всем и не только Unix администраторам.

Python для системных администраторов

Автор перевода messerr, просто с кармой ему не повезло.

Введение

О модулях

Модуль – важное понятие в языке Python. По существу, модуль – это ресурс, который вы подключаете к программе, чтобы затем использовать его. Этот процесс можно сравнить с тем, что вы достанете из ящика лист бумаги и положите его на свой стол, подготовив тем самым к дальнейшему использованию. Модули подключаются при помощи команды import, которая присутствует в начале каждого примера. Модули доступны для связи с базами данных, сетевого программирования, сервисов операционных систем и сотен других полезных областей.

Заставим Python работать

Python — полнофункциональный, надежный язык программирования и, по существу, имеет массу свойств. Изучение его может стать задачей эпических масштабов. Однако, помните, что многие способности, такие как GUI инструментарий, имеют для системного администратора низкую ценность. Вот почему в этой статье используются специфичные примеры: они демонстрируют навыки, необходимые для эффективного написания скриптов управления системой.

Немного о примерах:

  • Каждый пример использует try: и except: с блоком кода внутри. Это осуществляет элементарную обработку ошибок. Python имеет обширную поддержку для обработки всех видов исключений, но, в рамках примеров этой статьи, я обошелся простой проверкой.
  • Эти примеры тестировались с помощью Python 2.5, запущенном на Linux® box, но они должны работать на любой Unix/Linux машине.

Вы несомненно задумаетесь об улучшении этих скриптов. Это хорошо! Натура Python-скриптов заключается в том, что они могут быть легко модифицированы и настроены без необходимости перекомпиляции.

Пример 1: Поиск файлов и отображение прав в дружественном формате

Первый пример (Листинг 1) осуществляет поиск файлов, в соответствии с шаблоном (который вводит пользователь) и выводит результат на экран вместе с правами доступа для каждого файла. Во-первых, вы можете подумать, что эта программа не делает ничего большего, чем вызов команды find; однако она отображает результаты особым образом и ваши варианты отображения этого расширенного поиска безграничны.
Скрипт по существу решает три задачи:

  1. Получает шаблон поиска от пользователя
  2. Выполняет поиск
  3. Показывает результаты пользователю

При написании скрипта постоянно задавайте себе вопрос, «Выполнение какой задачи данный код обеспечивает?» Задавая себе этот вопрос, вы повышаете внимание в вашей работе и ее эффективность.

Листинг 1. Поиск файлов и отображение результатов с правами доступа.

# -*- coding: utf-8 -*-
import stat, sys, os, string, commands
#Записываем в переменную шаблон поиска, введенный пользователем
try:
pattern = raw_input(«Введите шаблон поиска:n»)
#запускаем команду ‘find’ и присваиваем результат переменной
commandString = «find » + pattern
commandOutput = commands.getoutput(commandString)
findResults = string.split(commandOutput, «n»)
#выводим найденные файлы вместе с правами доступа
print «Файлы:»
print commandOutput
print «================================»
for file in findResults:
mode=stat.S_IMODE(os.lstat(file)[stat.ST_MODE])
print «nPermissions for file «, file, «:»
for level in «USR», «GRP», «OTH»:
for perm in «R», «W», «X»:
if mode & getattr(stat,»S_I»+perm+level):
print level, » имеет «, perm, » права доступа»
else:
print level, » не имеет «, perm, » прав доступа»
except:
print «Возникла проблема! Проверьте сообщение выше.»

Программа следует по следующим этапам:

  1. Запрашивает у пользователя шаблон поиска (строки 7-9).
  2. Печатает список найденных файлов (строки 12-14).
  3. Используя модуль stat, получает права доступа для каждого найденного файла и отображает их на экране (строки 15-23).

Результат работы программы показан в Листинге 2.

$ python example1.py
Enter the file pattern to search for:
j*.py

Листинг 2. Вывод первого примера

$ python example1.py
Введите шаблон поиска:
j*.py
Файлы:
jim.py
jim2.py

================================
Permissions for file jim.py :
USR имеет R права доступа
USR имеет W права доступа
USR не имеет X прав доступа
GRP имеет R права доступа
GRP не имеет W прав доступа
GRP не имеет X прав доступа
OTH имеет R права доступа
OTH не имеет W прав доступа
OTH не имеет X прав доступа
Permissions for file jim2.py :
USR имеет R права доступа
USR имеет W права доступа
USR не имеет X прав доступа
GRP имеет R права доступа
GRP не имеет W прав доступа
GRP не имеет X прав доступа
OTH имеет R права доступа
OTH не имеет W прав доступа
OTH не имеет X прав доступа

Пример 2: Выполнение операций с архивом tar при помощи меню

Предыдущий пример для своей работы запрашивал у пользователя поисковый шаблон. Другой способ получить от пользователя информацию — аргумент в командной строке. Программа в Листинге 3 показывает как сделать это в Python: код берет имя файла tar, как аргумент командной строки и затем предложит пользователю несколько опций. Этот пример так же показывает новый способ решения проблемы. Первый пример использовал модуль команд для запуска find и захвата вывода. Этот подход можно назвать неуклюжим и не очень «питоновским». Этот пример использует для открытия tar файла модуль tarfile, преимущество которого в том, что он позволяет Вам использовать атрибуты и методы Python при манипуляции с файлами. При помощи многих модулей Python, вы можете делать вещи, недоступные через командную строку. Этой хороший пример использования меню в Python. Программа выполняет различные действия в зависимости от вашего выбора:

  • Если вы нажмете 1, программа предложит выбрать файл в архиве для извлечения в текущую директорию и затем извлечет файл.
  • Если вы нажмете 2, программа предложит выбрать файл и затем покажет информацию о нем.
  • Если вы нажмете 3, программа выведет список всех файлов в архиве.

Листинг 3. Выполнение операций с архивом tar при помощи меню

# -*- coding: utf-8 -*-
import tarfile, sys
try:
#открываем tar-файл
tar = tarfile.open(sys.argv[1], «r:tar»)
#выводим меню и сохраняем выбор
selection = raw_input(«Введитеn
1 чтобы извлечь файлn
2 чтобы вывести информацию о файле в архивеn
3 чтобы показать все файлы в архивеnn»)
#выполняем действия, основанные на выборе
if selection == «1»:
filename = raw_input(«введите имя файла для извлечения: «)
tar.extract(filename)
elif selection == «2»:
filename = raw_input(«введите имя файла для просмотра: «)
for tarinfo in tar:
if tarinfo.name == filename:
print «n
Имя файла:tt», tarinfo.name, «n
Размер:tt», tarinfo.size, «байтn»
elif selection == «3»:
print tar.list(verbose=True)
except:
print «При выполнении программы возникла проблема!»

Программа следует по следующим этапам:

  1. Открывает tar файл (строка 5).
  2. Выводит на экран меню и получает выбор пользователя (строки 8-11).
  3. Если вы нажали 1 (строки 14-16), извлекает файл из архива.
  4. Если вы нажали 2 (строки 17-23), предоставляет информацию о выбранном файле.
  5. Если вы нажали 3 (строки 24-25), предоставляет информацию о всех файлах в архиве.

Результат работы программы показан в Листинге 4.

Листинг 4. Меню пользователя для второго примера

$ python example2.py jimstar.tar
Введите
1 чтобы извлечь файл
2 чтобы вывести информацию о файле в архиве
3 чтобы показать все файлы в архиве

Пример 3. Проверка запущенного процесса и отображение информации в дружественном представлении.

Одной из важнейших обязанностей системного администратора является проверка запущенных процессов. Скрипт в Листинге 5 даст вам несколько идей. Программа использует преимущества возможностей Unix: команда grep использует вывод, генерированный другой командой. Это позволит вам уменьшить объем данных, которые в дальнейшем будет анализировать Python.
Программа так же использует модуль string. Изучите этот модуль — вы будете часто его использовать.

Листинг 5. Отображение информации о запущенном процессе в дружественном представлении

# -*- coding: utf-8 -*-
import commands, os, string
program = raw_input(«Введите имя программы для проверки: «)
try:
#выполняем команду ‘ps’ и присваиваем результат списку
output = commands.getoutput(«ps -f|grep » + program)
proginfo = string.split(output)
#выводим результат
print «n
Путь:tt», proginfo[5], «n
Владелец:ttt», proginfo[0], «n
ID процесса:tt», proginfo[1], «n
ID родительского процесса:t», proginfo[2], «n
Время запуска:tt», proginfo[4]
except:
print «При выполнении программы возникла проблема!»

Программа следует по следующим этапам:

  1. Получает имя процесса для проверки и присваивает его переменной (строка 3).
  2. Запускает команду ps и добавляет результат в список (строки 7-8).
  3. Выводит детальную информацию о процессе (строки 11-16).
  4. Результат работы программы показан в Листинге 6.

Листинг 6. Вывод третьего примера

$ python example3.py
Введите имя программы для проверки: xterm
Путь: pts/0
Владелец: goga
ID процесса: 26509
ID родительского процесса: 26493
Время запуска: 17:28

Пример 4. Проверка имен пользователей и паролей на соблюдение политики безопасности. Управление безопасностью важная часть работы для каждого системного администратора. Python делает эту работу проще, как показывает последний пример. Программа в Листинге 7 использует модуль pwd для доступа к базе данных паролей. Она проверяет имена пользователей и пароли на соблюдение политики безопасности (в данном случае, имена должны быть как минимум 6 символов в длину, пароли — 8 символов). Есть два предостережения:
Эта программа работает только если у вас есть полные права для доступа к /etc/passwd.
Если вы используете теневые пароли, скрипт работать не будет (однако, в Питон 2.5 есть модуль spwd, который решит эту проблему).

Листинг 7. Проверка имен пользователей и паролей на соблюдение политики безопасности

# -*- coding: utf-8 -*-
import pwd
#заводим счетчики
erroruser = []
errorpass = []
#получаем базу данных паролей
passwd_db = pwd.getpwall()
try:
#проверяем каждое имя пользователя и пароль на валидность
for entry in passwd_db:
username = entry[0]
password = entry [1]
if len(username)

Программа следует по следующим этапам:

  1. Инициализирует списки счетчиков (строки 4-5).
  2. Открывает базу данных паролей и записывает данные в список (строка 8).
  3. Проверяет имена пользователей и пароли на валидность (строки 12-18).
  4. Выводит имена и пароли, не соответствующие политике безопасности (строки 21-26).

Результат работы программы показан в Листинге 8.

Листинг 8. Вывод четвертого примера

$ python example4.py
Следующие пользователи имеют имена менее чем из 6 символов::
Guest
Следующие пользователи имеют пароли менее чем из 8 символов:
Guest
johnsmith
joewilson
suejones

Другое применение скриптов. Вы можете использовать Python по ряду направлений для управления системой. Одна из лучших вещей, которую вы можете сделать — проанализировать свою работу, определить какие задачи вы выполняете неоднократно и изучить модули Python, которые помогут вам решить эти задачи — почти наверняка, таковые найдутся. Некоторые области, где Python может быть отличным помощником:

  • Управление серверами: проверка патчей для конкретного приложения и их автоматическое обновление.
  • Журналирование: автоматическая отправка e-mail при появлении в логах особого вида ошибки.
  • Сеть: создание Telnet соединения к серверу и слежение за статусом соединения.

Тестирование web-приложений: использование свободно доступных инструментов для эмуляции веб-браузера и проверки веб-приложения на функциональность и производительность.
Это всего лишь несколько примеров — я уверен вы сможете добавить к ним свои собственные полезные идеи.

Python в системном администрировании UNIX и Linux, Гифт Н., Джонс Д., 2009

К сожалению, на данный момент у нас невозможно бесплатно скачать полный вариант книги.

Но вы можете попробовать скачать полный вариант, купив у наших партнеров электронную книгу здесь, если она у них есть наличии в данный момент.

Также можно купить бумажную версию книги здесь.

Python в системном администрировании UNIX и Linux, Гифт Н., Джонс Д., 2009.

Книга «Python в системном администрировании UNIX и Linux» демонстрирует, как эффективно решать разнообразные задачи управления серверами UNIX и Linux с помощью языка программирования Python. Каждая глава посвящена определенной задаче, например многозадачности, резервному копированию данных или созданию собственных инструментов командной строки, и предлагает практические методы ее решения на языке Python. Среди рассматриваемых тем: организация ветвления процессов и передача информации между ними с использованием сетевых механизмов, создание интерактивных утилит с графическим интерфейсом, организация взаимодействия с базами данных и создание приложений для Google Арр Engine. Кроме того, авторы книги создали доступную для загрузки и свободно распространяемую виртуальную машину на базе Ubuntu, включающую исходные тексты примеров из книги и способную выполнять примеры, использующие SNMP, IPython, SQLAlchemy и многие другие утилиты.
Издание рассчитано на широкий круг специалистов — всех, кто только начинает осваивать язык Python, будь то опытные разработчики сценариев на языках командной оболочки или относительно мало знакомые с программированием вообще.

Почему Python?
Если вы системный администратор, вам наверняка пришлось сталкиваться с Perl, Bash, ksh и некоторыми другими языками сценариев. Вы могли даже использовать один или несколько языков в своей работе. Языки сценариев часто позволяют выполнять рутинную, утомительную работу со скоростью и надежностью, недостижимой без них. Любой язык — это всего лишь инструмент, позволяющий выполнить работу. Ценность языка определяется лишь тем, насколько точно и быстро с его помощью можно выполнить свою работу. Мы считаем, что Python представляет собой ценный инструмент именно потому, что он дает возможность эффективно выполнять нашу работу.

Можно ли сказать, что Python лучше, чем Perl, Bash, Ruby или любой другой язык? На самом деле очень сложно дать такую качественную оценку, потому что всякий инструмент очень тесно связан с образом мышления программиста, использующего его. Программирование -это субъективный и очень личностный вид деятельности. Язык становится превосходным, только если он полностью соответствует потребностям программиста. Поэтому мы не будем доказывать, что язык Python лучше, но мы объясним причины, по которым мы считаем Python лучшим выбором. Мы также объясним, почему он так хорошо подходит для решения задач системного администрирования.

ОГЛАВЛЕНИЕ.
Предисловие.
Введение.
1. Введение.
Почему Python?.
Мотивация.
Основы.
Выполнение инструкций в языке Python.
Использование функций в языке Python.
Повторное использование программного кода с помощью инструкции import.
2. IPython.
Установка IPython.
Базовые понятия.
Справка по специальным функциям.
Командная оболочка UNIX.
Сбор информации.
Автоматизация и сокращения.
В заключение.
3. Текст.
Встроенные компоненты Python и модули.
Анализ журналов.
ElementTree.
В заключение.
4. Создание документации и отчетов.
Автоматизированный сбор информации.
Сбор информации вручную.
Форматирование информации.
Распространение информации.
В заключение.
5. Сети.
Сетевые клиенты.
Средства вызова удаленных процедур.
SSH.
Twisted.
Scapy.
Создание сценариев с использованием Scapy.
6. Данные.
Введение.
Использование модуля OS для взаимодействия с данными.
Копирование, перемещение, переименование и удаление данных.
Работа с путями, каталогами и файлами.
Сравнение данных.
Объединение данных.
Поиск файлов к каталогов по шаблону.
Обертка для raync.
Метаданные: данные о данных.
Архивирование, сжатие, отображение и восстановление.
Использований модуля tarfile для создания архивов TAR.
Использование модуля tarfile для проверки содержимого файлов TAR.
7. SNMP.
Введение.
Краткое введение в SNMP.
IPython и Net-SNMP.
Исследование центра обработки данных.
Получение множества значений с помощью SNMP.
Создание гибридных инструментов SNMP.
Расширенна возможностей Net-SNMP.
Управление устройствами через SNMP.
Интеграция SNMP в сеть предприятия с помощью Zenoss.
8. Окрошка из операционных систем.
Введение.
Кросс-платформенное программирование на языке Python в UNIX.
Pylnotify.
OS X.
Администрирование систем Red Hat Linux.
Администрирование Ubuntu.
Администрирование систем Solaria.
Виртуализация.
Облачная обработка данных.
Использование Zenoss для управления серверами Windows из Linux.
9. Управление пакетами.
Введение.
Setuptools и пакеты Python Eggs.
Использование easy_install.
Дополнительные особенности casy_install.
Создание пакетов.
Точки входа и сценарии консоли.
Регистрация пакета в Python Package Index.
Distutils.
Buildout.
Использование Buildout.
Разработка с использованием Buildout.
virtualenv.
Менеджер пакетов ЕРМ.
10. Процессы и многозадачность.
Введение.
Модуль subprocess.
Использование программы Supervisor для управления процессами.
Использование программы screen для управления процессами.
Потоки выполнения в Python.
Процессы.
Модуль processing.
Планирование запуска процессов Python.
Запуск демона.
В заключение.
11. Создание графического интерфейса.
Теория создания графического интерфейса.
Создание простого приложения РуСТК.
Создание приложения PyGTK для просмотра файла журнала веб-сервера Apache.
Создание приложения для просмотра файла журнала веб-сервера Apache с использованием curses.
Веб-приложения.
Django.
В заключение.
12. Сохранность данных.
Простая сериализация.
Реляционная сериализация.
В заключение.
13. Командная строка.
Введение.
Основы использования потока стандартного ввода.
Введение в optparse.
Простые шаблоны использования optparse.
Внедрение команд оболочки в инструменты командной строки на языке Python.
Интеграция конфигурационных файлов.
В заключение.
14. Практические примеры.
Управление DNS с помощью сценариев на языке Python.
Использование протокола LDAP для работы с OpenLDAP, Active Directory и другими продуктами из сценариев на языке Python.
Составление отчета на основе файлов журналов Apache.
Зеркало FTP.
Приложение, Функции обратного вызова.
Алфавитный указатель.

По кнопкам выше и ниже «Купить бумажную книгу» и по ссылке «Купить» можно купить эту книгу с доставкой по всей России и похожие книги по самой лучшей цене в бумажном виде на сайтах официальных интернет магазинов Лабиринт, Озон, Буквоед, Читай-город, Литрес, My-shop, Book24, Books.ru.

По кнопке «Купить и скачать электронную книгу» можно купить эту книгу в электронном виде в официальном интернет магазине «ЛитРес» , и потом ее скачать на сайте Литреса.

По кнопке «Найти похожие материалы на других сайтах» можно найти похожие материалы на других сайтах.

On the buttons above and below you can buy the book in official online stores Labirint, Ozon and others. Also you can search related and similar materials on other sites.