sp-tutorial 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|