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
|
---
category: tool
tool: bash
contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
translators:
- ["Ehreshi Ivan", "https://github.com/IvanEh"]
- ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"]
lang: uk-ua
---
Bash - командна оболонка unix (unix shell), що також розповсюджувалась як оболонка для
операційної системи GNU і зараз використовується як командна оболонка за замовчуванням
для Linux i Max OS X.
Майже всі приклади, що наведені нижче можуть бути частиною shell-скриптів або
виконані в оболонці
[Більш детально тут.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
# Перший рядок скрипта - це shebang, який вказує системі, як потрібно виконувати
# скрипт. Як ви вже зрозуміли, коментарі починаються з #. Shebang - також коментар
# Простий приклад hello world:
echo Hello world!
# Окремі команди починаються з нового рядка або розділяються крапкою з комкою:
echo 'Перший рядок'; echo 'Другий рядок'
# Оголошення змінної
VARIABLE="Просто рядок"
# Але не так!
VARIABLE = "Просто рядок"
# Bash вирішить, що VARIABLE - це команда, яку він може виконати,
# і видасть помилку, тому що не зможе знайти її
# І так також не можна писати:
VARIABLE= 'Просто рядок'
# Bash сприйме рядок 'Просто рядок' як команду. Але такої команди не має, тому
# видасть помилку.
# (тут 'VARIABLE=' інтерпретується як присвоєння тільки в контексті
# виконання команди 'Просто рядок')
# Використання змінних:
echo $VARIABLE
echo "$VARIABLE"
echo '$VARIABLE'
# Коли ви використовуєте змінну - присвоюєте значення, експортуєте і т.д. -
# пишіть її імя без $. А для отримання значення змінної використовуйте $.
# Одинарні лапки ' не розкривають значення змінних
# Підстановка рядків в змінні
echo ${VARIABLE/Просто/A}
# Цей вираз замінить перше входження підрядка "Просто" на "А"
# Отримання підрядка із рядка
LENGTH=7
echo ${VARIABLE:0:LENGTH}
# Цей вираз поверне тільки перші 7 символів змінної VARIABLE
# Значення за замовчуванням
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
# Це спрацює при відсутності значення (FOO=) і при пустому рядку (FOO="")
# Нуль (FOO=0) поверне 0.
# Зауважте, що у всіх випадках значення самої змінної FOO не зміниться
# Вбудовані змінні:
# В bash є корисні вбудовані змінні, наприклад
echo "Значення, яке було повернуте в останній раз: $?"
echo "PID скрипта: $$"
echo "Кількість аргументів: $#"
echo "Аргументи скрипта: $@"
echo "Аргументи скрипта, розподілені по різним змінним: $1 $2..."
# Зчитування змінних з пристроїв введення
echo "Як вас звати?"
read NAME # Зверніть увагу, що вам не потрібно оголошувати нову змінну
echo Привіт, $NAME!
# В bash є звичайна умовна конструкція if:
# наберіть 'man test', щоб переглянути детальну інформацію про формати умов
if [ $NAME -ne $USER ]
then
echo "Ім’я користувача не збігається з введеним"
else
echo "Ім’я збігаєтьяс з іменем користувача"
fi
# Зауважте! якщо $Name пуста, bash інтерпретує код вище як:
if [ -ne $USER ]
# що є неправильним синтаксисом
# тому безпечний спосіб використання потенційно пустих змінних має вигляд:
if [ "$Name" -ne $USER ] ...
# коли $Name пуста, інтерпретується наступним чином:
if [ "" -ne $USER ] ...
# що працює як і очікувалося
# Умовне виконання (conditional execution)
echo "Виконується завжди" || echo "Виконається, якщо перша команда завершиться з помилкою"
echo "Виконується завжди" && echo "Виконається, якщо перша команда завершиться успішно"
# Щоб використати && і || у конструкції if, потрібно декілька пар дужок:
if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
then
echo "Виконається, якщо $NAME="Steve" i AGE=15."
fi
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
then
echo "Виконається, якщо NAME="Steve" або NAME="Zach"."
fi
# Вирази позначаються наступним форматом:
echo $(( 10 + 5 ))
# На відміну від інших мов програмування, Bash - це командна оболонка, а
# отже, працює в контексті поточної директорії
ls
# Ця команда може використовуватися з опціями
ls -l # Показати кожен файл і директорію на окремому рядку
# Результат попередньої команди можна перенаправити на вхід наступної.
# Команда grep фільтрує вхід по шаблону.
# Таким чином ми можемо переглянути тільки *.txt файли в поточній директорії:
ls -l | grep "\.txt"
# Ви можете перенаправити вхід і вихід команди (stdin, stdout, stderr).
# Наступна команда означає: читати із stdin, поки не зустрінеться ^EOF$, і
# перезаписати hello.py наступними рядками (до рядка "EOF"):
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# Запуск hello.py з різними варіантами перенаправлення stdin,
# stdout, stderr (стандартні потоки введення, виведення і помилок):
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# Потік помилок перезапише файл, якщо цей файл існує
# тому, якщо ви хочете дописувати до файлу, використовуйте ">>":
python hello.py >> "output.out" 2>> "error.err"
# Перезаписати output.txt, дописати error.err і порахувати кількість рядків:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# Запустити команду і вивести її файловий дескриптор (див.: man fd; наприклад /dev/fd/123)
echo <(echo "#helloworld")
# Перезаписати output.txt рядком "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Очистити тимчасові файли з детальним виводом (додайте '-i'
# для інтерактивного режиму)
rm -v output.out error.err output-and-error.log
# Команди можуть бути підставлені в інші команди використовуючи $():
# наступна команда виводить кількість файлів і директорій в поточній директорії
echo "Тут $(ls | wc -l) елементів."
# Те саме можна зробити використовуючи зворотні лапки
# Але вони не можуть бути вкладеними, тому перший варіант бажаніший
echo "Тут `ls | wc -l` елементів."
# В Bash є структура case, яка схожа на switch в Java и C++:
case "$VARIABLE" in
# перерахуйте шаблони, які будуть використовуватися в якості умов
0) echo "Тут нуль.";;
1) echo "Тут один.";;
*) echo "Не пусте значення.";;
esac
# Цикл for перебирає елементи передані в аргумент:
# Значення $VARIABLE буде надруковано тричі.
for VARIABLE in {1..3}
do
echo "$VARIABLE"
done
# Aбо можна використати звичний синтаксис for:
for ((a=1; a <= 3; a++))
do
echo $a
done
# Цикл for можно використати, щоб виконувати дії над файлами.
# Цей код запустить команду 'cat' для файлів file1 и file2
for VARIABLE in file1 file2
do
cat "$VARIABLE"
done
# ... або дії над виводом команд
# Запустимо cat для виведення із ls.
for OUTPUT in $(ls)
do
cat "$OUTPUT"
done
# Цикл while:
while [ true ]
do
echo "Тіло циклу..."
break
done
# Ви також можете оголосити функцію
# Оголошення:
function foo ()
{
echo "Аргументи функції доступні так само, як і аргументи скрипта: $@"
echo "$1 $2..."
echo "Це функція"
return 0
}
# Або просто
bar ()
{
echo "Інший спосіб оголошення функцій!"
return 0
}
# Виклик функцій
foo "Мое имя" $NAME
# Є багато корисних команд:
# вивести останні 10 рядків файла file.txt
tail -n 10 file.txt
# вивести перші 10 рядків файла file.txt
head -n 10 file.txt
# відсортувати рядки file.txt
sort file.txt
# відібрати або пропустити рядки, що дублюються (з опцією -d відбирає)
uniq -d file.txt
# вивести тільки першу колонку перед символом ','
cut -d ',' -f 1 file.txt
# замінити кожне 'okay' на 'great' у файлі file.txt (підтримується regex)
sed -i 's/okay/great/g' file.txt
# вивести в stdout всі рядки з file.txt, що задовольняють шаблону regex;
# цей приклад виводить рядки, що починаються на foo і закінчуються на bar:
grep "^foo.*bar$" file.txt
# використайте опцію -c, щоб вивести кількість входжень
grep -c "^foo.*bar$" file.txt
# щоб здійснити пошук по рядку, а не по шаблону regex, використовуйте fgrea (або grep -F)
fgrep "^foo.*bar$" file.txt
# Читайте вбудовану документацію Bash командою 'help':
help
help help
help for
help return
help source
help .
# Читайте Bash man-документацію
apropos bash
man 1 bash
man bash
# Читайте документацію info (? для допомоги)
apropos info | grep '^info.*('
man info
info info
info 5 info
# Читайте bash info документацію:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```
|