sp-tutorial 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +42 -0
- data/Rakefile +36 -0
- data/TODO +6 -0
- data/VERSION.yml +4 -0
- data/config.ru +15 -0
- data/lib/config.ru +15 -0
- data/lib/public/doc/Cyklop-otf-0_91.zip +0 -0
- data/lib/public/doc/ex/sp_lab01_zad.odt +0 -0
- data/lib/public/doc/ex/sp_lab02_zad.odt +0 -0
- data/lib/public/doc/ex/sp_lab03_zad.odt +0 -0
- data/lib/public/doc/ex/sp_lab04_zad.odt +0 -0
- data/lib/public/doc/latexsheet.pdf +0 -0
- data/lib/public/doc/survival.pdf +0 -0
- data/lib/public/images/Thatll_Flat_Git_It_Vol_20.jpg +0 -0
- data/lib/public/images/alan_kay.jpg +0 -0
- data/lib/public/images/alan_perlis.jpg +0 -0
- data/lib/public/images/albert_einstein.jpg +0 -0
- data/lib/public/images/algorithm.png +0 -0
- data/lib/public/images/biuletyn-snall.jpg +0 -0
- data/lib/public/images/bop.jpg +0 -0
- data/lib/public/images/borenstein.jpg +0 -0
- data/lib/public/images/commits.png +0 -0
- data/lib/public/images/gitk-branches.png +0 -0
- data/lib/public/images/jkew.jpg +0 -0
- data/lib/public/images/jwz.gif +0 -0
- data/lib/public/images/knuth.jpg +0 -0
- data/lib/public/images/marcin_wolinski.jpg +0 -0
- data/lib/public/images/objects-example.png +0 -0
- data/lib/public/images/perlis.gif +0 -0
- data/lib/public/images/real_programmers.png +0 -0
- data/lib/public/images/richard_stallman.jpg +0 -0
- data/lib/public/images/sp.png +0 -0
- data/lib/public/images/sp.svg +117 -0
- data/lib/public/images/spowrotem.jpg +0 -0
- data/lib/public/images/staging_area.png +0 -0
- data/lib/public/images/the_thinker.jpg +0 -0
- data/lib/public/images/tparr.jpg +0 -0
- data/lib/public/images/wide-gitk.gif +0 -0
- data/lib/public/javascripts/sp.js +1 -0
- data/lib/public/stylesheets/fonts/Cyklop-Italic.otf +0 -0
- data/lib/public/stylesheets/icons/doc.png +0 -0
- data/lib/public/stylesheets/icons/email.png +0 -0
- data/lib/public/stylesheets/icons/external.png +0 -0
- data/lib/public/stylesheets/icons/feed.png +0 -0
- data/lib/public/stylesheets/icons/im.png +0 -0
- data/lib/public/stylesheets/icons/pdf.png +0 -0
- data/lib/public/stylesheets/icons/visited.png +0 -0
- data/lib/public/stylesheets/icons/xls.png +0 -0
- data/lib/public/stylesheets/ie.css +27 -0
- data/lib/public/stylesheets/print.css +30 -0
- data/lib/public/stylesheets/screen.css +249 -0
- data/lib/public/stylesheets/sp.css +194 -0
- data/lib/public/stylesheets/src/grid.png +0 -0
- data/lib/public/stylesheets/uv.css +121 -0
- data/lib/sp-tutorial.rb +78 -0
- data/lib/views/answers.rdiscount +7 -0
- data/lib/views/exercises.rdiscount +154 -0
- data/lib/views/favicon.ico.rdiscount +0 -0
- data/lib/views/git.rdiscount +558 -0
- data/lib/views/labs01.rdiscount +54 -0
- data/lib/views/labs02.rdiscount +32 -0
- data/lib/views/labs03.rdiscount +28 -0
- data/lib/views/labs04.rdiscount +41 -0
- data/lib/views/latex.rdiscount +498 -0
- data/lib/views/layout.rdiscount +41 -0
- data/lib/views/ll.rdiscount +78 -0
- data/lib/views/main.rdiscount +67 -0
- data/lib/views/scripts.rdiscount +618 -0
- data/lib/views/unix-commands.rdiscount +604 -0
- data/lib/views/unix-guru.rdiscount +696 -0
- data/sp-tutorial.gemspec +125 -0
- 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 ( | ), 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 \( \\ \)?
|
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"
|