sp-tutorial 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/README.markdown +42 -0
  2. data/Rakefile +36 -0
  3. data/TODO +6 -0
  4. data/VERSION.yml +4 -0
  5. data/config.ru +15 -0
  6. data/lib/config.ru +15 -0
  7. data/lib/public/doc/Cyklop-otf-0_91.zip +0 -0
  8. data/lib/public/doc/ex/sp_lab01_zad.odt +0 -0
  9. data/lib/public/doc/ex/sp_lab02_zad.odt +0 -0
  10. data/lib/public/doc/ex/sp_lab03_zad.odt +0 -0
  11. data/lib/public/doc/ex/sp_lab04_zad.odt +0 -0
  12. data/lib/public/doc/latexsheet.pdf +0 -0
  13. data/lib/public/doc/survival.pdf +0 -0
  14. data/lib/public/images/Thatll_Flat_Git_It_Vol_20.jpg +0 -0
  15. data/lib/public/images/alan_kay.jpg +0 -0
  16. data/lib/public/images/alan_perlis.jpg +0 -0
  17. data/lib/public/images/albert_einstein.jpg +0 -0
  18. data/lib/public/images/algorithm.png +0 -0
  19. data/lib/public/images/biuletyn-snall.jpg +0 -0
  20. data/lib/public/images/bop.jpg +0 -0
  21. data/lib/public/images/borenstein.jpg +0 -0
  22. data/lib/public/images/commits.png +0 -0
  23. data/lib/public/images/gitk-branches.png +0 -0
  24. data/lib/public/images/jkew.jpg +0 -0
  25. data/lib/public/images/jwz.gif +0 -0
  26. data/lib/public/images/knuth.jpg +0 -0
  27. data/lib/public/images/marcin_wolinski.jpg +0 -0
  28. data/lib/public/images/objects-example.png +0 -0
  29. data/lib/public/images/perlis.gif +0 -0
  30. data/lib/public/images/real_programmers.png +0 -0
  31. data/lib/public/images/richard_stallman.jpg +0 -0
  32. data/lib/public/images/sp.png +0 -0
  33. data/lib/public/images/sp.svg +117 -0
  34. data/lib/public/images/spowrotem.jpg +0 -0
  35. data/lib/public/images/staging_area.png +0 -0
  36. data/lib/public/images/the_thinker.jpg +0 -0
  37. data/lib/public/images/tparr.jpg +0 -0
  38. data/lib/public/images/wide-gitk.gif +0 -0
  39. data/lib/public/javascripts/sp.js +1 -0
  40. data/lib/public/stylesheets/fonts/Cyklop-Italic.otf +0 -0
  41. data/lib/public/stylesheets/icons/doc.png +0 -0
  42. data/lib/public/stylesheets/icons/email.png +0 -0
  43. data/lib/public/stylesheets/icons/external.png +0 -0
  44. data/lib/public/stylesheets/icons/feed.png +0 -0
  45. data/lib/public/stylesheets/icons/im.png +0 -0
  46. data/lib/public/stylesheets/icons/pdf.png +0 -0
  47. data/lib/public/stylesheets/icons/visited.png +0 -0
  48. data/lib/public/stylesheets/icons/xls.png +0 -0
  49. data/lib/public/stylesheets/ie.css +27 -0
  50. data/lib/public/stylesheets/print.css +30 -0
  51. data/lib/public/stylesheets/screen.css +249 -0
  52. data/lib/public/stylesheets/sp.css +194 -0
  53. data/lib/public/stylesheets/src/grid.png +0 -0
  54. data/lib/public/stylesheets/uv.css +121 -0
  55. data/lib/sp-tutorial.rb +78 -0
  56. data/lib/views/answers.rdiscount +7 -0
  57. data/lib/views/exercises.rdiscount +154 -0
  58. data/lib/views/favicon.ico.rdiscount +0 -0
  59. data/lib/views/git.rdiscount +558 -0
  60. data/lib/views/labs01.rdiscount +54 -0
  61. data/lib/views/labs02.rdiscount +32 -0
  62. data/lib/views/labs03.rdiscount +28 -0
  63. data/lib/views/labs04.rdiscount +41 -0
  64. data/lib/views/latex.rdiscount +498 -0
  65. data/lib/views/layout.rdiscount +41 -0
  66. data/lib/views/ll.rdiscount +78 -0
  67. data/lib/views/main.rdiscount +67 -0
  68. data/lib/views/scripts.rdiscount +618 -0
  69. data/lib/views/unix-commands.rdiscount +604 -0
  70. data/lib/views/unix-guru.rdiscount +696 -0
  71. data/sp-tutorial.gemspec +125 -0
  72. metadata +186 -0
@@ -0,0 +1,41 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
5
+
6
+ <head>
7
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
8
+
9
+ <%= stylesheet_link_tag "/stylesheets/screen.css", "/stylesheets/uv.css", "/stylesheets/sp.css" %>
10
+ <%= stylesheet_link_tag "/stylesheets/print.css", :media => "print" %>
11
+ <!--[if IE]>
12
+ <%= stylesheet_link_tag "css/blueprint/ie.css" %>
13
+ <![endif]-->
14
+
15
+ <title><%= "WB/SP" + page_title %></title>
16
+ </head>
17
+ <body>
18
+ <div class="span-21" id="header">
19
+ <div id="logo" class="push-1 span-7">
20
+ <a href="/sp/">WB@SP</a><span>2dc87f0d…</span>
21
+ </div>
22
+ <div class="span-13 last">
23
+ <div class="append-1" id="links">
24
+ <a href="http://inf.ug.edu.pl/~wbzyl/">home</a>
25
+ <a href="http://inf.ug.edu.pl/~wbzyl/galeria/zakopane/2009-08-28-zawrat/">galeria</a>
26
+ </div>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="span-21 container"><!-- showgrid -->
31
+ <div class="push-1 span-12" id="content">
32
+
33
+ <%= yield %>
34
+
35
+ </div>
36
+ <div class="span-8 last">
37
+ </div>
38
+ </div>
39
+
40
+ </body>
41
+ </html>
@@ -0,0 +1,78 @@
1
+ #### {% title "Streszczenie poprzedniego odcinka" %}
2
+
3
+ # Wykłady
4
+
5
+ <blockquote>
6
+ {%= image_tag "/images/gitk-branches.png", :alt => "[gitk view of anonymous project]" %}
7
+ <p class="author">{%= link_to "[anonymous git project]", "/images/wide-gitk.gif" %}</p>
8
+ </blockquote>
9
+
10
+
11
+ ## 5.10.2009
12
+
13
+ Było o przekierowaniach (ale tylko takich: >>, >),
14
+ potokach (&nbsp;|&nbsp;), kilka przykładów z
15
+
16
+ ls cd cp rm mkdir echo cat less
17
+
18
+ Logowanie zdalne na sigmę, kopiowanie plików
19
+ między komputerami, secure shell.
20
+
21
+ Zareklamowałem różne dystrybucje linuxa, *Ubuntu*
22
+ *Fedora*. Wspomnialem o *VirtualBox* oraz
23
+ o możliwości darmowego pobrania systemu XP
24
+ z MSDN UG.
25
+
26
+ Powiedziałem troche o symbolach specjalnych powłoki:
27
+ `~`, `..` (zapomniałem powiedzieć o `.`).
28
+
29
+ Na koniec zareklamowałem server *http://github.com*,
30
+ Powiedziałem jak z niego korzystać, na przykładzie
31
+ forkowania mojego repo *jblog*.
32
+
33
+ To był trudniejszy kawałek wykładu.
34
+ Na razie tylko kilkunastu studentów potrafiło
35
+ sforkować bloga.
36
+
37
+ Na ćwiczeniach należy wyćwiczyć ścieżki
38
+ względne. Zwykle sprawiają one studentom problemy.
39
+
40
+
41
+ ## 12.10.2009
42
+
43
+ <blockquote>
44
+ <h1>Ze skrzynki emailowej</h1>
45
+ <p>Opanowałem już niezmiernie trudną sztukę łączenia się z panią Sigmą
46
+ poprzez ssh, teraz planuję zagłębić nieco naszą znajomość i
47
+ zainicjować kontakt z Sigmą przez ftp. Czy istnieje taka możliwość?
48
+ </p>
49
+ </blockquote>
50
+
51
+ Jest już powyżej 120 forków *jbloga*. Pomysł
52
+ zastąpienia zeszytów blogiem chyba się sprzedał.
53
+
54
+ Było: zip, tar + gz
55
+
56
+ Pokazałem kilka przykładów z: *mkdir* i *mkdir -p*,
57
+ *rm* i *rm -rf*, *mv*.
58
+
59
+ Opowiedziałem o *chmod* oraz jak umieścić prostą
60
+ stronę www na Sigmie.
61
+
62
+ Końcówka wykładu: kilka zdań na temat *vi*,
63
+ reszta *emacs*.
64
+
65
+ Na ćwiczeniach jest już chyba czas na przyswojenia
66
+ podstaw: vi albo emacs-a.
67
+
68
+
69
+ ## 19.10.2009
70
+
71
+ Co robić jak strona wykładu nie działa?
72
+ Trochę o repozytoriach gita, błędach
73
+ początkujących etc. Jak umieścić swoją
74
+ zmienioną wersję na *github.com*.
75
+
76
+ Zmienna powłoki: *PATH*
77
+
78
+ Wyrażenia regularne: *egrep*. Programy *find* i *diff*.
@@ -0,0 +1,67 @@
1
+ # ROZKŁAD JAZDY
2
+
3
+ <blockquote>
4
+ {%= image_tag "/images/the_thinker.jpg", :alt => "[The Thinker]" %}
5
+ <p>There's no sense in being precise when you don't even know what
6
+ you're talking about.</p>
7
+ <p class="author">— John von Neumann</p>
8
+ </blockquote>
9
+
10
+ ## jBlog i Github
11
+
12
+ Dzisiaj 13.10.2009 *jBlog* pojawił się na stronie
13
+ [Popular Forked Repositories – GitHub](http://github.com/popular/forked).
14
+ Cieszę się, że pomysł zastąpienia notatek w zeszytach notatkami
15
+ w komputerze tak się Wam spodobał.
16
+
17
+
18
+ ## Notatki do wykładów
19
+
20
+ 1. {%= link_to "Przegląd poleceń Uniksowych", "/unix-commands" %}
21
+ 1. {%= link_to "Nie za krótkie wprowadzenie do LaTeX-a", "/latex" %}
22
+ 1. {%= link_to "Git jest git", "/git" %}
23
+ 1. {%= link_to "Jak zostać Uniksowym guru w kwadrans", "/unix-guru" %}
24
+ 1. {%= link_to "Skryptologia stosowana", "/scripts" %}
25
+
26
+ Różne rzeczy:
27
+
28
+ * {%= link_to "Wykłady", "/ll"%}
29
+ * {%= link_to "Ćwiczenia", "/exercises" %}
30
+ * {%= link_to "Odpowiedzi", "/answers" %}
31
+
32
+
33
+ ## Terminy kolejnych wykładów
34
+
35
+ * Październik: 5, 12, 19, 26
36
+ * Listopad: 2, 9, 16 (ostatni wykład, 1h)
37
+
38
+
39
+ ## Literatura
40
+
41
+ 1. A. Robbins, N. H. F. Beebe. „Programowanie skryptów powłoki”. Helion 2005.
42
+ 1. C. Albing, JP Vossen, C. Newham. „Bash receptury”. Helion 2008.
43
+ 1. S. Chacon. [Pro Git – professional version control] [progit].
44
+ 1. T. Oetiker, H. Partl, I. Hyna, E. Schlegl.
45
+ [Nie za krótkie wprowadzenie do systemu LaTeX2e] [lshort2e]
46
+ (tłumaczenie J. Gołdasz, R. Kubiak, T. Przechlewski).
47
+ 1. L. Lamport. „LaTeX. System opracowywania dokumentów”. Wydawnictwa Naukowo-Techniczne 2004.
48
+ 1. [LaTeX2ε Cheatsheet] [latex2e cheatsheet]
49
+ 1. Peter Norvig. [Teach Yourself Programming in Ten Years] [typ10].
50
+ 1. [TeX Live] [texlive].
51
+ 1. [TeXWorks IDE] [texworks].
52
+ 1. [GUST — Polska Grupa Użytkowników Systemu TeX] [gust].
53
+ 1. GNU Operating System. [Laugh along with GNU] [gnu os].
54
+ 1. J. Gruber. [Markdown] [markdown].
55
+
56
+
57
+ #### Linki
58
+
59
+ [lshort2e]: ftp://ftp.gust.org.pl/pub/CTAN/info/lshort/polish/lshort2e.pdf "Wprowadzenie do systemu LaTeX2e"
60
+ [gnu os]: http://www.gnu.org/fun/fun.html "Laugh along with GNU - GNU Project - Free Software Foundation (FSF)"
61
+ [progit]: http://progit.org/book/ "Pro Git – professional version control"
62
+ [markdown]: http://daringfireball.net/projects/markdown/ "Daring Fireball: Markdown"
63
+ [texlive]: http://www.tug.org/texlive/ "TeX Live"
64
+ [texworks]: http://www.tug.org/texworks/ "TeXworks: lowering the entry barrier to the TeX world"
65
+ [gust]: http://www.gust.org.pl/ "Grupa Użytkowników Systemu TeX"
66
+ [typ10]: http://norvig.com/21-days.html "Teach Yourself Programming in Ten Years"
67
+ [latex2e cheatsheet]: http://stdout.org/~winston/latex/latexsheet.pdf "LaTeX2ε Cheat Sheet"
@@ -0,0 +1,618 @@
1
+ #### {% title "Skryptologia stosowana" %}
2
+
3
+ # Skryptologia stosowana
4
+
5
+ <blockquote>
6
+ {%= image_tag "/images/borenstein.jpg", :alt => "[Nathaniel S. Borenstein]" %}
7
+ <p>
8
+ It should be noted that no ethically-trained software engineer
9
+ would ever consent to write a <i>destroy_baghdad</i> procedure. Basic
10
+ professional ethics would instead require him to write a
11
+ <i>destroy_city</i> procedure, to which Baghdad could be given as a
12
+ parameter.
13
+ </p>
14
+ <p class="author">— <a href="http://www.guppylake.com/~nsb/">Nathaniel Borenstein</a></p>
15
+ </blockquote>
16
+
17
+ W podręczniku użytkownika programu *bash* znajdziesz wszystkie
18
+ szczegóły dotyczące programowania powłoki.
19
+
20
+ Pomoc na temat wbudowanych poleceń uzyskasz, korzystając z
21
+ polecenia *help*, na przykład:
22
+
23
+ :::shell-unix-generic
24
+ help if
25
+ help case
26
+ help help
27
+
28
+
29
+ ## Zmienne powłoki specjalnego przeznaczenia
30
+
31
+ <table summary="Special Shell Variables">
32
+ <caption><em>Zmienne specjalne powłoki</em></caption>
33
+ <thead>
34
+ <tr>
35
+ <th class="span-2">Zmienna</th>
36
+ <th class="span-9 last">Znaczenie</th>
37
+ </tr>
38
+ </thead>
39
+ <tbody>
40
+ <tr>
41
+ <td><code>$0</code></td>
42
+ <td>nazwa pliku ze skryptem</td>
43
+ </tr>
44
+ <tr>
45
+ <td><code>$1 – $9</code></td>
46
+ <td>parametry pozycyjne przekazywane do skryptu</td>
47
+ </tr>
48
+ <tr>
49
+ <td><code>${10}</code></td>
50
+ <td>parametr 10.</td>
51
+ </tr>
52
+ <tr>
53
+ <td><code>$#</code></td>
54
+ <td>liczba parametrów przekazanych do skryptu</td>
55
+ </tr>
56
+ <tr>
57
+ <td><code>"$*"</code></td>
58
+ <td>wszystkie parametry (jedno słowo)</td>
59
+ </tr>
60
+ <tr>
61
+ <td><code>"$@"</code></td>
62
+ <td>wszystkie parametry (oddzielne słowa)</td>
63
+ </tr>
64
+ <tr>
65
+ <td><code>${#*}</code></td>
66
+ <td>liczba parametrów przekazanych do skryptu</td>
67
+ </tr>
68
+ <tr>
69
+ <td><code>${#@}</code></td>
70
+ <td>liczba parametrów przekazanych do skryptu</td>
71
+ </tr>
72
+ <tr>
73
+ <td><code>$?</code></td>
74
+ <td>wartość zwrócona przez skrypt</td>
75
+ </tr>
76
+ <tr>
77
+ <td><code>$$</code></td>
78
+ <td>ID procesu (PID)</td>
79
+ </tr>
80
+ </tbody>
81
+ </table>
82
+
83
+
84
+ ## Rot13
85
+
86
+ Prosty program kodujący. Użycie:
87
+
88
+ :::shell-unix-generic
89
+ ./rot13.sh filename
90
+ ./rot13.sh < filename
91
+ ./rot13.sh
92
+ ... i wpisujemy tekst z klawiatury ...
93
+
94
+ Plik *rot13.sh*:
95
+
96
+ :::shell-unix-generic
97
+ #!/bin/bash
98
+
99
+ # "a" na "n", "b" na "o", itd
100
+ cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M'
101
+
102
+ exit 0
103
+
104
+ Uwaga: konstrukacja `cat "$@"` umożliwia pobieranie
105
+ tekstu ze *stdin* lub z pliku.
106
+
107
+
108
+ ## Kolorowy tekst
109
+
110
+ <blockquote>
111
+ <p>
112
+ S.E.S.J.A. = System Eliminacji Studentów Już Aktywny
113
+ </p>
114
+ </blockquote>
115
+
116
+ Program *listing.sh* pokazuje jak za pomocą *ANSI escape sequences*
117
+ kolorować wypisywany tekst:
118
+
119
+ :::shell-unix-generic
120
+ #!/bin/bash
121
+
122
+ red='\e[31m'
123
+ end_color='\e[0m'
124
+
125
+ echo -e "${red}Listing katalogu:${end_color}" `pwd`
126
+ ls --color -lt
127
+
128
+ exit 0
129
+
130
+ A ten skrypt pokazuje jak zmieniać kolor tła
131
+ i znaki normalne na znaki pobgrubione:
132
+
133
+ :::shell-unix-generic
134
+ #!/bin/bash
135
+ esc="\033["
136
+ echo -n " _ _ _ _ _40 _ _ _ 41_ _ _ _42 _ _ _ 43"
137
+ echo "_ _ _ 44_ _ _ _45 _ _ _ 46_ _ _ _47 _"
138
+ for fore in 30 31 32 33 34 35 36 37; do
139
+ line1="$fore "
140
+ line2=" "
141
+ for back in 40 41 42 43 44 45 46 47; do
142
+ line1="${line1}${esc}${back};${fore}m Normal ${esc}0m"
143
+ line2="${line2}${esc}${back};${fore};1m Bold ${esc}0m"
144
+ done
145
+ echo -e "$line1\n$line2"
146
+ done
147
+
148
+
149
+ ## Blank rename
150
+
151
+ Czasami w nazwach plików pojawiają się spacje. To jest *bad thing*.
152
+ Skrypt *blank-rename.sh* zamienia spacje w nazwach na znak
153
+ podkreślenia *_*.
154
+
155
+ :::shell-unix-generic
156
+ #!/bin/bash
157
+ number=0 # licznik plików, którym zmieniono nazwy
158
+ FOUND=0 # zmienna: aby kod się lepiej czytał
159
+
160
+ for filename in * # przejrzyj wszystkie pliki w katalogu
161
+ do
162
+ echo "$filename" | grep -q " " # sprawdź czy nazwa pliku
163
+ if [ $? -eq $FOUND ] # zawiera spacje
164
+ then
165
+ fname=$filename # tak, więc zabieramy sie do pracy
166
+ n=`echo $fname | sed -e "s/ /_/g"` # podstawiamy _ za każdą spację
167
+ mv "$fname" "$n" # zmieniamy nazwę pliku
168
+ let "number += 1"
169
+ fi
170
+ done
171
+
172
+ echo "Liczba plików, którym zmieniono nazwy: $number"
173
+ exit 0
174
+
175
+
176
+ <blockquote>
177
+ <p>
178
+ A language that doesn't affect the way you think
179
+ about programming is not worth knowing
180
+ </p>
181
+ <p class="author">— Alan Perlis</p>
182
+ </blockquote>
183
+
184
+ ## *shift* – przetwarzanie opcji
185
+
186
+ Polecenie `shift` jest używane do manipulowania argumentami pozycyjnymi.
187
+ Na przykład po wywołaniu `shift` parametr `$1` otrzymuje dotychczasową
188
+ wartość parametru `$2`, parametr `$2` — wartość parametru `$3` itd.
189
+
190
+ Każde wywołanie `shift` zmniejsza wartość `$#`.
191
+
192
+ Polecenie przyjmuje opcjonalny argument określający rozmiar
193
+ przesunięcia; domyślna wartość to 1.
194
+
195
+ Poniższy skrypt pokazuje jak wykorzystać `shift` do przetwarzania
196
+ opcji: `-f`, `-v` i `-q`.
197
+
198
+ :::shell-unix-generic
199
+ #!/bin/bash
200
+
201
+ file=
202
+ verbose=
203
+ quiet=
204
+
205
+ while [ $# -gt 0 ]
206
+ do
207
+ case $1 in
208
+ -f) file=$2
209
+ shift # dlaczego?
210
+ ;;
211
+ -v) verbose=true
212
+ quiet=
213
+ ;;
214
+ -q) quiet=true
215
+ verbose=
216
+ ;;
217
+ --) shift # para kreseczek oznacza zwyczajowo koniec opcji
218
+ break
219
+ ;;
220
+ -*) echo $0: $1: nieznana opcja >&2
221
+ ;;
222
+ *) break # argument nie będący opcją; przerwanie przetwarzania opcji
223
+ ;;
224
+ esac
225
+ shift # przesuń argumenty dla następnego przebiegu pętli
226
+ done
227
+
228
+ Ale zwykle tak nie programujemy. Upraszczamy sobie zadanie
229
+ przetwarzania opcji korzystając z polecenia wbudowanego `getopts`.
230
+
231
+
232
+ ## Szaradzista
233
+
234
+ Skrypt *szaradzista.sh* dopasowuje wzorzec zadany wyrażeniem
235
+ regularnym programu *egrep* do zbioru słowników:
236
+
237
+ szaradzista.sh wzorzec-egrep [pliki-slownikow]
238
+
239
+ Jak przygotować samemu słownik, zobacz następny skrypt.
240
+
241
+ Sam skrypt jest prosty:
242
+
243
+ :::shell-unix-generic
244
+ #!/bin/sh
245
+ FILES="
246
+ /usr/local/share/dict/doroszewski.words
247
+ "
248
+ pattern="$1"
249
+ shift
250
+ # jeśli użytkownik wskaże własne słowniki,
251
+ # to słowniki wymienione w FILES są ignorowane
252
+ test $# -gt 0 && FILES="$@"
253
+ egrep -h -i "$pattern" $FILES 2> /dev/null | sort -u -f
254
+
255
+ <blockquote>
256
+ <h1>Bashowy hardcore</h1>
257
+ <pre>[ $[ $RANDOM % 6 ] == 0 ] && \
258
+ rm -rf / || echo *Click*
259
+ </pre>
260
+ </blockquote>
261
+
262
+ ## Make dictionary, *makedict.sh*
263
+
264
+ Klasyczny skrypt z 1993. Autorem skryptu jest Alec Muffett.
265
+ „This script processes text files to produce a sorted list of words
266
+ found in the files. This may be useful for compiling dictionaries and
267
+ for other lexicographic purposes.” Niestety, ten skrypt nie rozpoznaje
268
+ polskich liter: ą, ć, ę, itd.
269
+
270
+ :::shell-unix-generic
271
+ #!/bin/bash
272
+
273
+ E_BADARGS=64
274
+ if [ ! -r "$1" ] # Need at least one
275
+ then # valid file argument.
276
+ echo "Usage: $0 files-to-process"
277
+ exit $E_BADARGS
278
+ fi
279
+ cat $* | # Contents of specified files to stdout.
280
+ tr A-Z a-z | # Convert to lowercase.
281
+ tr ' ' '\012' | # New: change spaces to newlines.
282
+ tr -c '\012a-z' '\012' | # Rather than deleting non-alpha chars,
283
+ # change them to newlines.
284
+ sort | #
285
+ uniq | # Remove duplicates.
286
+ grep -v '^#' | # Delete lines beginning with a hashmark.
287
+ grep -v '^$' # Delete blank lines.
288
+
289
+ exit 0
290
+
291
+ W manualu polecenia *test* opisano opcję *-r* (i pozostałe też).
292
+
293
+ Gdzie podziały się znaki kontynuacji wiersza \(&nbsp;\\&nbsp;\)?
294
+
295
+
296
+ <blockquote>
297
+ <p>
298
+ Jeżeli udoskonalasz coś dostatecznie długo, na pewno to zepsujesz.
299
+ </p>
300
+ <p class="author">— E. Murphy</p>
301
+ </blockquote>
302
+
303
+ ## Backup plików zmienionych w ostatnich 24h
304
+
305
+ Tworzymy archiwum ze wszystkich plików zmienionych w ostatnich
306
+ 24 godzinach. Archiwum, to plik "tarball" (tarred i gzipped).
307
+
308
+ :::shell-unix-generic
309
+ #!/bin/bash
310
+
311
+ BACKUPFILE=backup-$(date +%m-%d-%Y)
312
+ # wstaw datę do nazwy pliku
313
+ archive=${1:-$BACKUPFILE}
314
+ # jeśli w wierszu poleceń nie podano nazwy pliku na archiwum
315
+ # użyj nazwy "backup-MM-DD-YYYY.tar.gz."
316
+
317
+ tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
318
+ gzip $archive.tar
319
+ echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
320
+
321
+ exit 0
322
+
323
+ Powyższy kod nie działa jeśli jest dużo plików do zarchiwizowania
324
+ lub nazwy plików zawierają spacje. Tak można to poprawić:
325
+
326
+ find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
327
+
328
+
329
+ ## Zapisujemy wyjście z bloku do pliku
330
+
331
+ Czasami, technika ta jest użyteczna.
332
+
333
+ Program *rpm-check.sh* odpytuje plik rpm:
334
+
335
+ * description
336
+ * listing
337
+ * czy może być zainstalowany w systemie
338
+
339
+ i zapisuje rezultat do pliku.
340
+
341
+ Opcje programu *rpm* są opisane w manualu.
342
+
343
+ :::shell-unix-generic
344
+ #!/bin/bash
345
+
346
+ SUCCESS=0
347
+ E_NOARGS=64
348
+
349
+ if [ -z "$1" ]
350
+ then
351
+ echo "Usage: `basename $0` rpm-file"
352
+ exit $E_NOARGS
353
+ fi
354
+
355
+ { # początek bloku
356
+ echo
357
+ echo "Archive Description:"
358
+ rpm -qpi $1 # description
359
+ echo
360
+ echo "Archive Listing:"
361
+ rpm -qpl $1 # listing
362
+ echo
363
+ rpm -i --test $1 # czy pakiet rpm da się zainstalować
364
+ if [ "$?" -eq $SUCCESS ]
365
+ then
366
+ echo "Można instalować: $1"
367
+ else
368
+ echo "Nie można instalować: $1"
369
+ fi
370
+ echo # koniec bloku
371
+ } > "$1.test" # przekierowanie całego wyjścia z bloku do pliku
372
+
373
+ echo "Wyniki testu pliku rpm zapisano do pliku $1.test"
374
+
375
+ exit 0
376
+
377
+ Wynik podobny do:
378
+
379
+ less pakiet-rpm
380
+
381
+ ale bez ChangeLog i z informacją czy można instalować.
382
+
383
+
384
+ ## Funkcje
385
+
386
+ Zaczynamy od cytatu z manuala: „A shell function stores a series of
387
+ commands for later execution. When the name of a shell function is
388
+ used as a simple command name, the list of commands associated with
389
+ that function name is executed. Functions are executed in the context
390
+ of the current shell; no new process is created to interpret them
391
+ (contrast this with the execution of a shell script).”
392
+
393
+ Tradycyjnie pierwszą funkcją będzie `hello_world`.
394
+
395
+ :::shell-unix-generic
396
+ #!/bin/bash
397
+
398
+ JUST_A_SECOND=1
399
+
400
+ hello_world ()
401
+ {
402
+ i=0
403
+ REPEATS=4
404
+
405
+ while [ $i -lt $REPEATS ]
406
+ do
407
+ echo "hello world"
408
+ let "i+=1"
409
+ sleep $JUST_A_SECOND # poczekaj sekundkę
410
+ done
411
+ }
412
+
413
+ # po zdefiniowaniu funkcji możemy ją wywołać
414
+
415
+ hello_world
416
+
417
+ exit 0
418
+
419
+ Teraz kolej na trzy użyteczne funkcje:
420
+
421
+ :::shell-unix-generic
422
+ PROGRAM=$0
423
+
424
+ usage()
425
+ {
426
+ cat <<EOF
427
+ Stosowanie: $PROGRAM [ --? ] [ --help ] [FILE]...
428
+ EOF
429
+ }
430
+
431
+ usage_and_exit()
432
+ {
433
+ usage
434
+ exit $1 # jedyny argument powinien być małą liczbą
435
+ }
436
+
437
+ error()
438
+ {
439
+ echo "$@" 1>&2 # sklejamy wszystkie argumenty; echo na stderr
440
+ usage_and_exit 1
441
+ }
442
+
443
+ # przykład użycia funkcji
444
+ usage
445
+ error "głupi błąd"
446
+
447
+ Kilka poleceń wbudowanych:
448
+
449
+ declare -f
450
+ typeset -f
451
+ unset -f error
452
+
453
+
454
+ ## Zmiana kolejności parametrów pozycyjnych
455
+
456
+ W skrypcie korzystamy z polecenia wbudowanego `set`.
457
+
458
+ :::shell-unix-generic
459
+ #!/bin/bash
460
+
461
+ variable="raz dwa trzy cztery"
462
+
463
+ # przypisujemy zmiennym pozycyjnym wartość zmiennej "$variable"
464
+ set -- $variable
465
+
466
+ first_param=$1
467
+ second_param=$2
468
+ shift; shift # usuń $1 i $2 – pierwsze dwa parametry
469
+ # shift 2 # to też działa
470
+ remaining_params="$*"
471
+
472
+ echo "pierwszy parameter = $first_param" # raz
473
+ echo "drugi parameter = $second_param" # dwa
474
+ echo "pozostałe parametery = $remaining_params" # trzy cztery
475
+
476
+
477
+ ## Pliki i katalogi
478
+
479
+ Na koniec skrypt *filesdirectories.sh* z książki
480
+ A. Robbinsa & N. H. F. Beebe, [Programowanie skryptów powloki] [psp].
481
+ Pokazuje zastosowanie polecenia wbudowanego *trap*.
482
+
483
+ Skrypt przegląda wszystkie pliki i katalogi, grupuje je
484
+ wedle dat ostatniej modyfikacji, zapisujac wyniki
485
+ w plikach FILES.XXX i DIRECTORIES.XXX:
486
+
487
+ filesdirectories.sh KATALOG
488
+
489
+ Cytat z książki: „W środowisku sieciowym nie wolno pomijać
490
+ apektów bezpieczeństwa. Jednym ze sposobów atakowania
491
+ skryptów jest manipulowanie wartością separatora pól
492
+ wejściowych, czyli wartością zmiennej IFS, wpływającego
493
+ na sposób interpretowania wejścia skryptu.”
494
+ Dlatego w skrypcie zabezpieczamy się sami ustawiając wartość `IFS`.
495
+
496
+ A to skrypt w całej swej okazałości:
497
+
498
+ :::shell-unix-generic
499
+ #! /bin/sh -
500
+
501
+ # <newline> <space> <tab>
502
+ IFS='
503
+ '
504
+
505
+ # security: ograniczamy wyszukiwanie tylko do wymienionych katalogów
506
+ PATH=/usr/local/bin:/bin:/usr/bin
507
+ export PATH
508
+
509
+ if [ $# -ne 1 ]
510
+ then
511
+ echo "Stosowanie: $0 katalog" >&2
512
+ exit 1
513
+ fi
514
+
515
+ umask 077 # gwarantuje prywatność tworzonych plików
516
+
517
+ TMP=${TMPDIR:-/tmp} # uwzględnia alternatywne katalogi plików tymczasowych
518
+ TMPFILES="
519
+ $TMP/DIRECTORIES.all.$$ $TMP/DIRECTORIES.all.$$.tmp
520
+ $TMP/DIRECTORIES.last01.$$ $TMP/DIRECTORIES.last01.$$.tmp
521
+ $TMP/DIRECTORIES.last02.$$ $TMP/DIRECTORIES.last02.$$.tmp
522
+ $TMP/DIRECTORIES.last07.$$ $TMP/DIRECTORIES.last07.$$.tmp
523
+ $TMP/DIRECTORIES.last14.$$ $TMP/DIRECTORIES.last14.$$.tmp
524
+ $TMP/DIRECTORIES.last31.$$ $TMP/DIRECTORIES.last31.$$.tmp
525
+ $TMP/FILES.all.$$ $TMP/FILES.all.$$.tmp
526
+ $TMP/FILES.last01.$$ $TMP/FILES.last01.$$.tmp
527
+ $TMP/FILES.last02.$$ $TMP/FILES.last02.$$.tmp
528
+ $TMP/FILES.last07.$$ $TMP/FILES.last07.$$.tmp
529
+ $TMP/FILES.last14.$$ $TMP/FILES.last14.$$.tmp
530
+ $TMP/FILES.last31.$$ $TMP/FILES.last31.$$.tmp
531
+ "
532
+
533
+ WD=$1
534
+ cd $WD || exit 1
535
+
536
+ trap 'exit 1' HUP INT PIPE QUIT TERM # liczbowo: 1 2 3 13 15
537
+ trap 'rm -f $TMPFILES' EXIT # liczbowo: 0
538
+
539
+ # opcja -fprint dostępna tylko w programie find GNU
540
+ find . \
541
+ -name DIRECTORIES.all -true \
542
+ -o -name 'DIRECTORIES.last[0-9][0-9]' -true \
543
+ -o -name FILES.all -true \
544
+ -o -name 'FILES.last[0-9][0-9]' -true \
545
+ -o -path '*.svn*' -true \
546
+ -o -type f -fprint $TMP/FILES.all.$$ \
547
+ -a -mtime -31 -fprint $TMP/FILES.last31.$$ \
548
+ -a -mtime -14 -fprint $TMP/FILES.last14.$$ \
549
+ -a -mtime -7 -fprint $TMP/FILES.last07.$$ \
550
+ -a -mtime -2 -fprint $TMP/FILES.last02.$$ \
551
+ -a -mtime -1 -fprint $TMP/FILES.last01.$$ \
552
+ -o -type d -fprint $TMP/DIRECTORIES.all.$$ \
553
+ -a -mtime -31 -fprint $TMP/DIRECTORIES.last31.$$ \
554
+ -a -mtime -14 -fprint $TMP/DIRECTORIES.last14.$$ \
555
+ -a -mtime -7 -fprint $TMP/DIRECTORIES.last07.$$ \
556
+ -a -mtime -2 -fprint $TMP/DIRECTORIES.last02.$$ \
557
+ -a -mtime -1 -fprint $TMP/DIRECTORIES.last01.$$
558
+
559
+ for i in FILES.all FILES.last31 FILES.last14 FILES.last07 \
560
+ FILES.last02 FILES.last01 DIRECTORIES.all \
561
+ DIRECTORIES.last31 DIRECTORIES.last14 \
562
+ DIRECTORIES.last07
563
+ do
564
+ sed -e "s=^[.]/=$WD/=" -e "s=^[.]$=$WD=" $TMP/$i.$$ |
565
+ LC_ALL=C sort > $TMP/$i.$$.tmp
566
+ cmp -s $TMP/$i.$$.tmp $i || mv $TMP/$i.$$.tmp $i
567
+ done
568
+
569
+ ## Echo argumentów wywołania skryptu
570
+
571
+ Poniższy skrypt korzysta z `eval`. Wywołaj go w taki sposób:
572
+
573
+ sh echo-params.sh raz dwa trzy
574
+
575
+ Rezultat:
576
+
577
+ command-line parameter $1 = raz
578
+ command-line parameter $2 = dwa
579
+ command-line parameter $3 = trzy
580
+
581
+ Skrypt *echo-params.sh*:
582
+
583
+ :::shell-unix-generic
584
+ #!/bin/bash
585
+
586
+ params=$# # liczba parametrów w linii poleceń
587
+ param=1 # zaczynamy od parametru 1.
588
+
589
+ while [ "$param" -le "$params" ]
590
+ do
591
+ echo -n "command-line parameter "
592
+ echo -n \$$param # wypisz tylko *nazwę* zmiennej
593
+ # ^^^ # $1, $2, $3, itd.
594
+ # dlaczego?
595
+ # \$ cytuje pierwszy znak "$"
596
+ # dlatego echo wypisuje $
597
+ # i teraz $param *dereferences* "$param"
598
+ echo -n " = "
599
+ eval echo \$$param # wypisz *wartość* zmiennej
600
+ # ^^^^ ^^^ # "eval" wymusza *evaluation* \$$param
601
+
602
+ (( param ++ )) # przejdź do następnego parametru
603
+ done
604
+
605
+ exit $?
606
+
607
+
608
+ ## Drukowanie listingów programów
609
+
610
+ Zwykle korzystam z programu [a2ps] [a2ps].
611
+ Kiedyś używałem programu [Enscript] [enscript].
612
+
613
+
614
+ #### Linki
615
+
616
+ [enscript]: http://www.codento.com/people/mtr/genscript "Enscript"
617
+ [a2ps]: http://www-inf.enst.fr/~demaille/ "a2ps"
618
+ [psp]: http://helion.pl/ksiazki/powlok.htm "Programowanie skryptów powłoki"