aboutsummaryrefslogtreecommitdiff
path: root/content/weblog/2018-12-31_intro-to-linux-and-bash-pt2/index.ru.md
blob: de4db1df9f42d7510cf31f86d04578e09f847b0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
+++
title = "Введение в Linux и Bash, часть II"
date = 2018-12-31T09:20:00Z
+++

И так, год подходит к концу, и я так еще не написал вторую часть туториала про
Bash и Linux. Надо бы написать хотя бы один пост в этом, последнем месяце года.

<!-- more -->

В этой части, я расскажу чуть больше про инструменты и команды в Linux и
Unix-подобных системах, которые вам пригодятся при работе в терминале. Все или
большинство из этих программ являются частью основного набора программ и утилит
большинства бистрибутивов Linux и Unix/Unix-подобных систем.

## Работа с файлами

В предыдущей части я стал объяснять подробно как работать с файлами. Однако,
возможность манипулировать файлы является очень полезным и важным функционалом
компьютерных систем.

### Создать файл

Обычно, если хотим создать файл, мы используем определенную программу специально
предназначена для создания и редактирования определенного вида файлов. Например,
vim для редактирования и записи текстовых файлов. Однако есть утилита которая
позволяет создавать пустые файлы - touch.

Вы можете создать пустой файл введя touch и последовательно название или путь
файла который вы хотите создать, например

```sh
user@host:~$ touch example.txt
```

А теперь у нас пустой файл в "/home/user/example.txt". Но, я немного соврал,
когда сказал что данная команда для того чтобы создавать пустые файлы. На самом
деле, она сначала проверяет наличия файла, затем, если он существует, она
редактировает его даты и время доступа и редактирования, иначе он создает пустой
файл, как в данном случае. Очень редко когда данная команда на самом деле
понадобится, поскольку в большинство случаях сами программы для редактирования
файлов могут также их создавать. Тем не менее бывают случаи когда она может
пригодится.

### Создать директорий

Сейчас у нас будет что-то поинтереснее, как создать директорий. Создавать
директории довольно просто, команда - mkdir. Например

```sh
user@host:~$ mkdir foo
```

Мы только что создали директорий "foo" в "/home/user/". Не забудьте что мы
всегда передаем путь файла, будь они относительными или абсолютными (если вы не
помните что это значит, прочитайте первую часть). В данном случае, мы используем
относительный путь содержающий только название директория.

Если бы мы использовали абсолютный путь, он выглядел бы таким образом -
"/home/user/foo". Нам бы пришлось убедиться в том что директории "home" и "user"
существуют. Однако, существует очень подезный флажок, которые мы можем передать
команде, чтобы она создавала родительские директории при необходимости - -p

```sh
user@host:~$ mkdir -p /tmp/foo/bar
```

Если директории "tmp" и/или "foo" не существуют, он их автоматический сделает,
вместе с "bar" внутри их.

### Перемещение и переименования

Это довольно просто, и обе действия можно выполнить одной командой - mv, что
происходит с английского move.

Если вам необходимо переименовать файл или директорий, переместите его в тот же
самый директорий, с новым/другим названием, например

```sh
user@host:~$ mv untitled titled
```

А вот если потребуется переместить в другую локацию, просто укажите путь новой
локации в качестве второго аргумента. Не забудьте что оба аргумента являются
путями, либо относительными либо абсолютными

```sh
user@host:~$ mv titled Documents/titled
```

### Копировать

Копирование похоже на перемещения, отличие просто в названии команды - cp.

```sh
user@host:~$ cp titled Documents/titled2
```

Однако, копирование директории отличается немного от копирования файлов. Чтобы
копировать директории, нужно использовать флаг -r. Он указывает что операция
должна быть рекурсивной, то есть, нужно скопировать каждый файл и поддиректорию
внутри директории (и файлы внутри этих поддиректории и в поддиректории
поддиректории и... ну то есть, рекурсия) в указанный путь. То есть что-то похоже
на это

```sh
user@host:~$ cp -r dir dir-copy
```

### Удалить

Удалять файлы довольно просто, достаточно ввести rm а затем путь файла

```sh
user@host:~$ rm title
```

Однако, чтобы удалять директории не так просто. Один способ - использовать
команду rmdir, но она только работает на пустых директориях.

Второй вариант, использовать ту же команду что и для файлов, но используя флаг
-r чтобы удалить файлы рекурсивно, также как и с командой cp. Будьте
внимательные при использовании этой команды, ибо она удаляет все файлы внутри
директории, вместе с директорией.

Итак, чтобы удалить директорию и все содержимое, нам понадобиться ввести
следующую команду

```sh
user@host:~$ rm -r dir
```

У этой команды есть еще один флаг, чтобы принудительно удалить файлы без
вопросов - флаг -f. Этот аргумент может пригодится, например, когда нужно
удалить сразу несколько файлов, и среди них есть специльные файлы, как скрытые
файлы (те, у которых точка перед названием) и вам не хочется подтвердить
действие перед каждым файлом.

Следует быть ОЧЕНЬ осторожным перед тем как использовать этот флаг, особенно
если вы собираетесь ввести команду под root пользователем. Поверьте, вам будет
очень неприятно если вы введете например "sudo rm -rf /" и у вас полетят
полностью система и файлы. Если вы не садист, конечно.

Пример ситуации когда данное сочетание флагов с командой rm может пригодится
это, когда вам необходимо удалить репозиторий git, поскольку в них содержатся
множество специальных скрытых файлов, которые git использует затем чтобы следить
за коммитами и прочее. Пример использования команды

```sh
user@host:~$ rm -rf somerepo
```

### Контроль доступа

В Unix и Unix-подобных системах существует довольно прочная система для контроля
прав доступа. Она позволяет определять полномочия определеных пользователей или
групп пользователей над определенными файлам, создавая безопасную среду для
компьютеров с множество пользователями.

У каждого файла три вида прав доступа, которые определяют что можно с ними
делать. Каждое право обозначается одной буквой английского алфавита

* r - чтение: пользователь имеет право читать данный файл.
* w - запись: пользователь может писать/редактровать данный файл (включая
  возможность его удалять).
* x - выполнение: файл может быть выполнен пользователем, если он является
  программой или скриптом.

Так же существует три разных наборов человек к которым могут относится права
доступа

* u - пользователь/владелец: пользователь, которому принадлежит файл. Обычно это
  тот же самый пользователь, который создал файл, но владелца можно поменять.
* g - группа: каждый принадлежит определенной группе пользователей. Это может
  быть группа одного пользователя (у каждого пользователя есть своя
  однопользовательская группа), или общая группа.
* o - другие: Все остальные кто не являются владелцем или ну состоит в группе.

Если вы читали первую часть туториала, вы наверное помните что я рассказывал про
команду "ls -l" чтобы посмотреть дополнительную информацию о файлах, включая
права доступа

```sh
user@host:~/Documents$ ls -l
drwxr-xr-x  2 user user  4.0K Jul  18 04:20 Books
-rwxr-xr--  1 user group 350  Jul  18 04:20 run.py
-rw-r--r--  1 user user  1.2M Jul  18 04:20 picture.png
```

Первые десять символов в каждой строке - права доступа для файла в данной
строке.

Первый символ в данном сочетаний символов определяет является ли файл обычным
файлом или другим видом. Если первым символом является буква d, то это
директория, если там просто черточка (тире/дефис), то это обычный файл. Там
также может быть другая буква, как например l для ссылок, но это уже не входит в
рамках данного поста.

Следующие 9 символов разделяются в свое время в сочетание из трех символов,
каждое для определенного набора пользователей. Первые три символа после символа
вида файла это права для владелца, следующие три для группы, и последние три для
отсальных.

В каждом из этих сочетании из трех букв, права доступа в порядке чтение, запись,
выполнение. Наличие буквы означает что у данного набора пользвателей данно это
право, отсуствие значит нет такого права для данного набора пользоваетелей.

Возьмем в качестве примера файл "run.py". Исходя из информации на экране мы
можем определить что это обычный файл (нет буквы d), владелец (user) имеет право
читать, записывать и выполнять его; группа пользователей (в группе group) имеет
право на чтение и выполнения, но не записи; и остальные только могут его читать.

Наверное вы заметили что почти всегда у директории присуствует право на
выполнение (буква x), однако это означает что-то немножко иное в отличие от
файлов. Буква "x" у директориях означает что есть право на вход в директорию и
есть доступ к файлам внутри директории. Право на чтения директории всего лишь
означает что можно смотреть на то какие файлы содержатся в директории, и право
на запись означает что есть то чтобы записывать файла внутри директории.

### Изменить права

Существует очень полезная команда которая позволяет менять права на доступ
файлов - chmod.

Чтобы изменить права на файле, необходимо ввести chmod и затем права и путь
файла. Есть два способа чтобы менять права, легкий но более долгий способ
используя буквы, и более быстрый но не совсем легкий используя восмеричный код.
Начнем с более легкого.

Более легкий способ состоит из трех частей

* Кто - пользователь/владелец, группа, остальные или все (u, g, o, или a)
* Дать или отменить право, "+" чтобы дать, "-" чтобы отменить
* Право которое мы меняем - чтение, запись или испольнение (r, w, или x)

Допустим у нас есть скрипт для которого мы хотим дать право на запуск для всех
пользователей.

```sh
user@host:~/Documents/stuff$ ls -l
-rw-r--r-- 1 user group  420  April 20 6:59  script.sh
user@host:~/Documents/stuff$ chmod a+x script.sh
-rwxr-xr-x 1 user group  420  April 20 6:59  script.sh
```

Как можно заметить, после запуска команды все пользователи компьютера имеют
право на выполнения скрипта. А теперь допустим что мы передумали и хотим
отменить право выполнения для всех пользователей кроме владелца, мы могли бы
ввести o-r и затем g-r, но мы можем также совмещать следующим образом

```sh
user@host:~/Documents/stuff$ chmod go-r script.sh
-rwx--x--x 1 user group  420  April 20 6:59  script.sh
```

А теперь пора выучить быстрый способ. Его сложнее запомнить, поскольку еще
нужны базовые понимания двоичной системы счисления. Грубо говоря, оно работает
подовая три цифры в восьмеричной системе счисления (то есть 0-7) каждая из
которых обозначает бит права для каждого набора пользователей
(пользователь/владелец, группа, другие).

Получается у нас три возможные права (чтение, запись и выполнение) и 2^3 нам
дает 8 возможных сочетании прав, и вот почему у нас восьмеричная система.
Следующая таблица поможет определить отношение нужной цифры для определенного
сочетания прав

<table>
  <tbody>
    <tr>
      <td>Восьмеричная система</td>
      <td>Двоичная система</td>
    </tr>
    <tr>
      <td>0</td>
      <td>001</td>
    </tr>
    <tr>
      <td>1</td>
      <td>001</td>
    </tr>
    <tr>
      <td>2</td>
      <td>010</td>
    </tr>
    <tr>
      <td>3</td>
      <td>011</td>
    </tr>
    <tr>
      <td>4</td>
      <td>100</td>
    </tr>
    <tr>
      <td>5</td>
      <td>101</td>
    </tr>
    <tr>
      <td>6</td>
      <td>110</td>
    </tr>
    <tr>
      <td>7</td>
      <td>111</td>
    </tr>
  </tbody>
</table>

Зная как переводятся цифры в двоичную становится намного проще знать к какой
комбинации прав она относится, ибо каждая цифра в сочетании трех бинарных цифр
относится к одному виду прав в выше указанному порядке (r, w, x). Если у нас
единица (1) это означает что есть данное право, а ноль (0) означает его
отсуствие. И так, например, 6 означает что у нас есть право на чтение и запись,
поскольку 6 = 110 = rw-.

Допустим что мы хотим поменять права доступа к файлу таким образом чтобы
владелец мог читать, записывать и выполнять; группа имела право на чтения и
выполнения; и остальные могли только выполнять. Для этого мы ввели что-то
подобное

```sh
user@host:~/Documents/stuff$ chmod 751 script.sh
user@host:~/Documents/stuff$ ls -l
-rwxr-x--x 1 user group  420  April 20 6:59  script.sh
```

Если вы меняете права доступа директория, новые права будут изменены только для
самой директории, не включая файлы и поддиректории внутри. Чтобы также изменить
права для всех файлов внутри директории, необходимо использовать флаг рекурсии -
-R (обратите внимания на то что, в chmod флаг рекурсии обозначается большой
буквой R в отличие от cp или rm).

### Поменять владелца

Менять владельца файла проще чем менять права. Чтобы поменять владельца необходимо
использовать команду chown. Например, допустим мы хотим поменять пользователя,
которого владеет файлом

```sh
user@host:~/.logs$ ls -l
-rw-r--r-- 1 root root  69  April 20 6:59  some.log
user@host:~/.logs$ sudo chown user some.log
user@host:~/.logs$ ls -l
-rw-r--r-- 1 user root  69  April 20 6:59  some.log
```

Поскольку файл не принадлежал тому же самому владельцу с которого мы выполняем
команды, нам необходимо выполнить команду через sudo чтобы повысить наши
права. Чтобы иметь возможность повышать права вашего пользователя, необходимо
чтобы ваш пользователь состоял в файле "sudoers" и/или в группе "wheel" зависимо
от дистрибутива/ОС. В большинство случаев (если вы пользуетесь
"домашним/дестктопным" дистро) у вас уже будут права на sudo, в любом случае
быстрый поиск в интернете поможет вам найти информацию о том как поменять
настройки прав в вашем дистрибутиве/ОС.

А теперь допустим что вы хотели поменять и пользователя и группу которому
принадлежит файл, в таком случае мы бы ввели следующее

```sh
user@host:~/.logs$ ls -l
-rw-r--r-- 1 root root  69  April 20 6:59  some.log
user@host:~/.logs$ sudo chown user:group some.log
user@host:~/.logs$ ls -l
-rw-r--r-- 1 user group  69  April 20 6:59  some.log
```

Также как и с chmod, если вам необходимо поменять владелца рекурсивной в
директории, вам нужно использовать флаг -R.

## Эпилог/Советы

В предыдущей части я забыл написать о том как ввести пути с пробедами. Нельзя
просто так печатать пути с пробелами, ибо пробел означает переход к следующему
аргументу.

Есть два способа печатать пути, названия файлов и другие аргументы с пробелами.
Первый способ - кавычки. Например

```sh
user@host:~/Documents$ rm "Shopping List.txt"
```

Второй - экранирования символа с помощью символа "\" перед пробелом. Например

```sh
user@host:~/Documents$ rm Shopping\ List.txt
```

Еще одно о чем я хотел рассказать - мануалы (man). Почти (если не все)
дистрибутивы Линукса имеют мануалы.

Не всегда необходимо обращаться к интернету если вы забыли как пользоваться
определнной командой. Если вы однажды оказались без интернета и вы хотите
узнать побольше об одной команде, man отличный оффлайн ресурс.

Не говоря уже о том что проще и быстрее делать все сразу с терминала не
переключаясь к браузеру чтобы искать нужную информацию.

Чтобы прочитать мануал определенной команды, введите man и затем название
команды. Например "man chmod".

Вы можете пользоваться клавишами vim (hjkl) для перемещения. Введите /<термин>
чтобы искать этот термин, а затем нажмите на n чтобы найти следующее совпадение.

Это все на данный момент. С новым 2019-м годом!