# Utiliser Python pour l'administration système

## Built-in functions

### Python `open` function

#### Open a file

See  
- [official doc](https://docs.python.org/3/library/functions.html#open)   
- [Official tutorial](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files)   

#### Manipulate file object

See    
- [official tutorial](https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects)   


## Default Librairies

### sys

#### Introduction

`sys` library gives us some infos about the system we are working on.

Import it in your code with `import sys`

#### Usage

| function  |  result  |
|-----------|----------|
| ` sys.getwindowsversion()` |  Return a named tuple describing the Windows version currently running.|
| ` sys.modules¶`  |  a dictionary that maps module names to modules which have already been loaded. | 
| `sys.platform`  |  a platform identifier ( `aix | linux | win32 | cygwin | darwin`)  |
| `sys.stdout`   | `stdout`  |
| `sys.stdin`   |  `stdin`  |  
|  `sys.stderr` | interpreter’s own prompts and its error messages  |
| ` sys.version¶` | version number of the Python interpreter |

#### Ressources for `sys` lib

See  
- [official doc](https://docs.python.org/3/library/sys.html)

### `platform`

Access to underlying platform’s identifying data

#### Usage

| function  |  result  |
|-----------|----------|
| ` platform.machine()` |  Returns the machine type, e.g. `i386` |
| ` platform.processor()` | Returns the (real) processor name, e.g. `amdk6` |
| ` platform.release()` |   Returns the system’s release, e.g. `2.2.0` or `NT` |
| ` platform.system()` |     Returns the system/OS name, such as `Linux`, `Darwin`, `Java`, `Windows` |
|  `platform.win32_ver()` |  return a tuple (release, version, csd, ptype) referring to OS release, version number, CSD level (service pack) and OS type (multi/single processor) |
| `platform.mac_ver()`  | Get Mac OS version information and return it as tuple (release, versioninfo, machine) |
| `platform.linux_distribution()` |  Tries to determine the name of the Linux OS distribution name. |


#### Ressources for `platform` lib

See  
- [official doc](https://docs.python.org/3/library/platform.html)

### os

#### Import `os` lib

```
import os
```

#### Unix-like commands

| unix  |  python  |
|-------|----------|
| `ls`  |  os.listdir |
| `rmdir`  | os.rmdir |
| `mkdir`  | os.mkdir  |
| `rm`     | os.remove |
| `chmod`  | os.chmod  |
| `chown`   |  os.chown |
|  `cd`     |  os.chdir  |
|  `pwd`    | os.getcwd  |
|  `uname`  |  os.uname  |
|  `mv`     |  os.replace |
|  `ln -s`  |  os.symlink |
|  `kill`   |  os.kill    |
|  `wait`   | os.wait  |


#### Scan a dir

##### Example 
```
with os.scandir(path) as it:
    for entry in it:
        if not entry.name.startswith('.') and entry.is_file():
            print(entry.name)
```

##### Doc  
See  
- [official doc](https://docs.python.org/3/library/os.html#os.scandir)

#### Doc for `os` lib

See  
- [official doc](https://docs.python.org/3/library/os.html)


### os.path

#### Import `os.path` lib

```
import os
```

#### Usage

| syntax   |  résultat  |
|----------|------------|
| `os.path.basename(path)` | Renvoie le nom de base du chemin d'accès `path`. |
| `os.path.dirname(path)` | Return the directory name of pathname `path`. |
| `os.path.isfile(path)` | Return true if `path` is an **existing** regular file ` |
| `os.path.isdir(path)` | Return true if `path` is an **existing** directory ` |
| `os.path.islink(path)` | Return true if `path` is asymbolinc link reffering to an **existing** directory ` |
| `os.path.ismount(path)` | Return true if `path` is a mountpoint ` | 
| `os.path.join(path, *paths)` |  Join one or more path components intelligently. | 
| `os.path.split(path)` | Split the pathname path into a pair, (head, tail) |


#### Doc for `os.path` lib

See  
- [official doc](https://docs.python.org/3/library/os.path.html)

### `shutils`

`shutils` offers high-level operations on files.

#### Usage

| unix  |  python  |
|-------|----------|
| `cp`  |  shutils.copy |
| `cp -R` | shutils.copytree | 
| `rm -R` |  shutils.rmtree | 
| `mv`    |  shutils.move  |
| `df`    |  shutils.disk_usage |


#### Doc for `shutils` lib

See  
- [official doc](https://docs.python.org/3/library/shutil.html)


### Rechercher un fichier

#### Avec `fnmatch`

##### Exemple  

```python
import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '*.txt'):
        print(file)
```

##### Ressources

See:  
- [official doc](https://docs.python.org/3/library/fnmatch.html)

#### Avec `glob`

##### Example

```python
>>> os.listdir(".")
['main.py', '.git', 'debian.py', 'README.md']
>>> 
>>> glob.glob('*.py')
['main.py', 'debian.py']
```
##### Ressources

See:  
- [official doc](https://docs.python.org/fr/3/library/glob.html)


### Gérer les processus

#### Utilisation de `subprocess`

```
>>> import subprocess as sub
>>> a = sub.run(['ls', '-l'],capture_output=True,text=True)
>>> print(a.stdout)
total 8
-rw-r--r-- 1 makayabou makayabou  0 nov.   5 01:54 debian.py
-rw-r--r-- 1 makayabou makayabou 34 nov.   4 20:47 main.py
-rw-r--r-- 1 makayabou makayabou 79 nov.   4 19:46 README.md

>>> print(a.returncode)
0
```

#### Utilisation de `shlex`

To avoid bash injection, it's good to use `shlex` to pass shell commands in a python script.

```python
>>> import shlex
>>> 
>>> command = "grep -irn python ."
>>> 
>>> split_command = shlex.split(command)
>>> 
>>> print(split_command)
['grep', '-irn', 'python', '.']
>>> 
>>> sub.run(split_command)
```

#### Ressources

See:  
- [official doc for subprocess](https://docs.python.org/3/library/subprocess.html)   
- [official doc for shlex](https://docs.python.org/3/library/shlex.html)

### Network library: `socket`

#### Usage

| command   |  result  |
|------------|-------------|
|  `socket.getfqdn([name])`  | Return a fully qualified domain name for name. |
|  ` socket.gethostbyname(hostname)` | Translate a host name to IPv4 address format. |
|  ` socket.gethostbyname_ex(hostname)`  |  Translate a host name to IPv4 address format, extended interface. |
| ` socket.gethostname()`   |  Return a string containing the hostname of the machine where the Python interpreter is currently executing.  |
| ` socket.gethostbyaddr(ip_address)` |  Return a triple (hostname, aliaslist, ipaddrlist)  |
| ` socket.bind(address)`  |  Bind the socket to address. |
| ` socket.connect(address)` |  Connect to a remote socket at address.  |
 

#### Ressources

See:  
- [official doc for `socket`](https://docs.python.org/3/library/socket.html)


### Créer une TUI 

Les `TUI` (Text User Interface) sont des interfaces en ligne de commande,
qui permettent de proposer un dialogue clair avec l'utilisateur.

On utilisera la librairie `curses`, équivalent de `ncurses` en bash.

#### Installation

```
import curses
```

#### Ressources

See:  
- [official doc for `curses`](https://docs.python.org/3/library/curses.html)  
- [official how-to for `curses`](https://docs.python.org/3/howto/curses.html)  
- [a tutorial on devdungeon.com](https://www.devdungeon.com/content/curses-programming-python)  


## Other modules to go further

### PsUtil

[psutil](https://pypi.org/project/psutil/) (process and system utilities) is a cross-platform library for retrieving information on running processes and system utilization (CPU, memory, disks, network, sensors.

```
pip install psutil
```

### PsDash


[psdash](https://pypi.org/project/psdash/) is a system information web dashboard for linux using data mainly served by psutil

```
pip install psdash
```


### Remote Resources MaNaGeMeNT

Remote Resources MaNaGeMeNT [(rrmngmt)](https://pypi.org/project/python-rrmngmnt/) helps you manage remote machines and services running on that. It is targeted to Linux based machines. All is done via SSH connection, that means SSH server must be running there already.

```
pip install python-rrmngmnt
```



