summaryrefslogtreecommitdiffhomepage
path: root/de-de/shutit-de.html.markdown
blob: 42875c99819ab3f527927a94828d78efc8712363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
---
category: framework
filename: learnshutit-de.html
framework: ShutIt
contributors:
    - ["Ian Miell", "http://ian.meirionconsulting.tk"]
translators:
    - ["Dennis Keller", "https://github.com/denniskeller"]
lang: de-de
---

## ShutIt

ShuIt ist eine Shellautomationsframework, welches für eine einfache 
Handhabung entwickelt wurde.

Er ist ein Wrapper, der auf einem Python expect Klon (pexpect) basiert.

Es ist damit ein 'expect ohne Schmerzen'.

Es ist verfügbar als pip install.

## Hello World

Starten wir mit dem einfachsten Beispiel. Erstelle eine Datei names example.py

```python
import shutit
session = shutit.create_session('bash')
session.send('echo Hello World', echo=True)
```

Führe es hiermit aus:

```bash
python example.py
```

gibt aus:

```bash
$ python example.py
echo "Hello World"
echo "Hello World"
Hello World
Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#
```

Das erste Argument zu 'send' ist der Befehl, den du ausführen möchtest.
Das 'echo' Argument gibt die Terminalinteraktion aus. ShuIt ist standardmäßig leise.

'Send' kümmert sich um die nervige Arbeiten mit den Prompts und macht 
alles was du von 'expect' erwarten würdest.


## Logge dich auf einen Server ein

Sagen wir du möchtest dich auf einen Server einloggen und einen Befehl ausführen.
Ändere dafür example.py folgendermaßen:

```python
import shutit
session = shutit.create_session('bash')
session.login('ssh you@example.com', user='du', password='meinpassword')
session.send('hostname', echo=True)
session.logout()
```

Dies erlaubt dir dich auf deinen Server einzuloggen
(ersetze die Details mit deinen Eigenen) und das Programm gibt dir deinen Hostnamen aus.

```
$ python example.py
hostname
hostname
example.com
example.com:cgoIsdVv:heDa77HB#
```


Es ist klar das das nicht sicher ist. Stattdessen kann man Folgendes machen:

```python
import shutit
session = shutit.create_session('bash')
password = session.get_input('', ispass=True)
session.login('ssh you@example.com', user='du', password=password)
session.send('hostname', echo=True)
session.logout()
```

Dies zwingt dich dein Passwort einzugeben:

```
$ python example.py
Input Secret:
hostname
hostname
example.com
example.com:cgoIsdVv:heDa77HB#
```


Die 'login' Methode übernimmt wieder das veränderte Prompt für den Login.
Du übergibst ShutIt den User und das Passwort, falls es benötigt wird,
mit den du dich einloggen möchtest. ShutIt übernimmt den Rest.

'logout' behandelt das Ende von 'login' und übernimmt alle Veränderungen des
Prompts für dich.

## Einloggen auf mehrere Server

Sagen wir, dass du eine Serverfarm mit zwei Servern hast und du dich in
beide Server einloggen möchtest. Dafür musst du nur zwei Session und 
Logins erstellen und kannst dann Befehle schicken:

```python
import shutit
session1 = shutit.create_session('bash')
session2 = shutit.create_session('bash')
password1 = session1.get_input('Password für server1', ispass=True)
password2 = session2.get_input('Password für server2', ispass=True)
session1.login('ssh you@one.example.com', user='du', password=password1)
session2.login('ssh you@two.example.com', user='du', password=password2)
session1.send('hostname', echo=True)
session2.send('hostname', echo=True)
session1.logout()
session2.logout()
```

Gibt aus:

```bash
$ python example.py
Password for server1
Input Secret:

Password for server2
Input Secret:
hostname
hostname
one.example.com
one.example.com:Fnh2pyFj:qkrsmUNs# hostname
hostname
two.example.com
two.example.com:Gl2lldEo:D3FavQjA#
```

## Beispiel: Überwachen mehrerer Server

Wir können das obige Programm in ein einfaches Überwachungstool bringen indem 
wir Logik hinzufügen um die Ausgabe von einem Befehl zu betrachten.

```python
import shutit
capacity_command="""df / | awk '{print $5}' | tail -1 | sed s/[^0-9]//"""
session1 = shutit.create_session('bash')
session2 = shutit.create_session('bash')
password1 = session.get_input('Passwort für Server1', ispass=True)
password2 = session.get_input('Passwort für Server2', ispass=True)
session1.login('ssh you@one.example.com', user='du', password=password1)
session2.login('ssh you@two.example.com', user='du', password=password2)
capacity = session1.send_and_get_output(capacity_command)
if int(capacity) < 10:
	print(kein Platz mehr auf Server1!')
capacity = session2.send_and_get_output(capacity_command)
if int(capacity) < 10:
	print(kein Platz mehr auf Server2!')
session1.logout()
session2.logout()
```

Hier kannst du die 'send\_and\_get\_output' Methode verwenden um die Ausgabe von dem 
Kapazitätsbefehl (df) zu erhalten.

Es gibt elegantere Wege als oben (z.B. kannst du ein Dictionary verwenden um über 
die Server zu iterieren), aber es hängt and dir wie clever das Python sein muss.


## kompliziertere IO - Expecting

Sagen wir du hast eine Interaktion mit einer interaktiven Kommandozeilenprogramm, 
die du automatisieren möchtest. Hier werden wir Telnet als triviales Beispiel verwenden:

```python
import shutit
session = shutit.create_session('bash')
session.send('telnet', expect='elnet>', echo=True)
session.send('open google.com 80', expect='scape character', echo=True)
session.send('GET /', echo=True, check_exit=False)
session.logout()
```

Beachte das 'expect' Argument. Du brauchst nur ein Subset von Telnets 
Eingabeaufforderung um es abzugleichen und fortzufahren.

Beachte auch das neue Argument 'check\_exit'. Wir werden nachher nochmal 
darauf zurückkommen. Die Ausgabe von oben ist:

```bash
$ python example.py
telnet
telnet> open google.com 80
Trying 216.58.214.14...
Connected to google.com.
Escape character is '^]'.
GET /
HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA
Content-Length: 261
Date: Sun, 04 Jun 2017 10:57:10 GMT

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.co.uk/?gfe_rd=cr&amp;ei=huczWcj3GfTW8gfq0paQDA">
here
</A>.
</BODY></HTML>
Connection closed by foreign host.
```

Nun zurück zu 'check\_exit=False'. Da das Telnet Programm einen Fehler mit 
Fehlercode (1) zurückgibt und wir nicht möchten das das Skript fehlschlägt
kannst du 'check\_exit=False' setzen und damit ShuIt wissen lassen, dass 
der Ausgabecode dich nicht interessiert.

Wenn du das Argument nicht mitgegeben hättest, dann hätte dir ShutIt 
ein interaktives Terminal zurückgegeben, falls es ein Terminal zum
kommunizieren gibt. Dies nennt sich ein 'Pause point'.


## Pause Points

Du kannst jederzeit 'pause point' auslösen, wenn du Folgendes in deinem Skript aufrufst:

```python
[...]
session.pause_point('Das ist ein pause point')
[...]
```

Danach kannst du das Skript fortführen, wenn du CTRL und ']' zur selben Zeit drückst.
Dies ist gut für Debugging: Füge ein Pause Point hinzu und schaue dich um.
Danach kannst du das Programm weiter ausführen. Probiere folgendes aus:

```python
import shutit
session = shutit.create_session('bash')
session.pause_point('Schaue dich um!')
session.send('echo "Hat dir der Pause point gefallen?"', echo=True)
```

Dies würde folgendes ausgeben:

```bash
$ python example.py
Schaue dich um!

Ians-Air.home:ORIGIN_ENV:I00LA1Mq#  bash
imiell@Ians-Air:/space/git/shutit  ⑂ master +    
CTRL-] caught, continuing with run...
2017-06-05 15:12:33,577 INFO: Sending:  exit
2017-06-05 15:12:33,633 INFO: Output (squashed):  exitexitIans-Air.home:ORIGIN_ENV:I00LA1Mq#  [...]
echo "Hat dir der Pause point gefallen?"
echo "Hat dir der Pause point gefallen?"
Hat dir der Pause point gefallen?
Ians-Air.home:ORIGIN_ENV:I00LA1Mq#
```


## noch kompliziertere IO - Hintergrund

Kehren wir zu unseren Beispiel mit dem Überwachen von mehreren Servern zurück.
Stellen wir uns vor, dass wir eine langlaufende Aufgabe auf jedem Server durchführen möchten.
Standardmäßig arbeitet ShutIt seriell, was sehr lange dauern würde.
Wir können jedoch die Aufgaben im Hintergrund laufen lassen um sie zu beschleunigen.

Hier ist ein Beispiel, welches du ausprobieren kannst.
Es verwendet den trivialen Befehl: 'sleep'.


```python
import shutit
import time
long_command="""sleep 60"""
session1 = shutit.create_session('bash')
session2 = shutit.create_session('bash')
password1 = session1.get_input('Password for server1', ispass=True)
password2 = session2.get_input('Password for server2', ispass=True)
session1.login('ssh you@one.example.com', user='du', password=password1)
session2.login('ssh you@two.example.com', user='du', password=password2)
start = time.time()
session1.send(long_command, background=True)
session2.send(long_command, background=True)
print('Es hat: ' + str(time.time() - start) + ' Sekunden zum Starten gebraucht')
session1.wait()
session2.wait()
print('Es hat:' + str(time.time() - start) + ' Sekunden zum Vollenden gebraucht')
```

Mein Computer meint, dass er 0.5 Sekunden gebraucht hat um die Befehle zu starten 
und dann nur etwas über eine Minute gebraucht um sie zu beenden
(mit Verwendung der 'wait' Methode).


Das alles ist trivial, aber stelle dir vor das du hunderte an Servern so managen
kannst und man kann nun das Potential sehen, die in ein paar Zeilen Code und ein Python 
import liegen können.


## Lerne mehr

Es gibt noch viel mehr, was mit ShutIt erreicht werden kann.

Um mehr zu erfahren, siehe:

[ShutIt](https://ianmiell.github.io/shutit/)
[GitHub](https://github.com/ianmiell/shutit/blob/master/README.md)

Es handelt sich um ein breiteres Automatiesierungsframework, und das oben
genannte ist der sogennante 'standalone Modus'.

Feedback, feature requests, 'Wie mache ich es' sind herzlich willkommen! Erreiche mit unter
[@ianmiell](https://twitter.com/ianmiell)