## 3. Файлы и программы

## 3.1. Файлы: предварительные понятия

Linux имеет структуру каталогов и файлов, очень похоже на DOS/Win. Файлы имеют имена, которые подчиняются специальным правилам, хранятся в каталогах, некоторые являются выполнимыми, и большинство из них имеют командные ключи. Кроме того, Вы можете использовать маски имен файлов, перенаправление ввода-вывода и конвейеры. Только имеется несколько маленьких отличий:

- Под DOS, имена файла находятся в так называемой форме 8.3, например, `NOTENOUG.TXT`. Под Linux наши возможности шире. Если Вы используете файловую систему Linux наподобие ext2 или umsdos, то Вы можете использовать более длинные имена файла (до 255 символов), и с имени может быть более одной точки, например, `this_is.a.VERY_long.filename`. Пожалуйста, обратите внимание, что я использовал, и верхний, и нижний регистр букв: фактически ...
- верхний и нижний регистр символов в именах файла или командах различаются. Следовательно, `FILENAME.tar.gz` и `filename.tar.gz` - два различных файла. `ls` - команда, `LS` - несуществующая команда;
- пользователи Windows 95, будьте осторожны при использовании длинных имен файлов под Linux. Если имя файла содержит пробелы (не рекомендуется, но возможно), Вы должны включить имя файла в двойные кавычки всякий раз, когда Вы обращаетесь к нему. Например:

  > `

  >            $ # the following command makes a directory called "My old files"

  >            $ mkdir "My old files"

  >            $ ls

  >            My old files    bin     tmp

  > `

  Далее, некоторые символы не должны использоваться: некоторые - это `! * $ &`.
- обязательные расширения типа .COM и .EXE для программ или .BAT для командных файлов не требуются. Когда Вы выдаете команду ls -F, исполняемые файлы отмечаются звездочкой "`*`" в конце их имени. Например:

  > `

  >            $ ls -F

  >            I_am_a_dir/   cindy.jpg    cjpg*   letter_to_Joe    my_1st_script*  old~

  > `

  Файлы `cjpg*` и `my_1st_script*` являются выполнимыми, то есть программами. Под DOS, резервные файлы заканчиваются в .BAK, в то время как под Linux они заканчивают тильдой "`~`". Далее, файл, чье имя начинается с точки, считается скрытым. Пример: файл `.I.am.a.hidden.file` не будет показан командой `ls`;
- ключи DOS программ указываются как `/switch`, в Linux как `-switch` или `--switch`. Пример: `dir /s` соотвествует `ls -R`. Заметьте, что многие DOS программы, типа `PKZIP` или `ARJ`, используют ключи как в UNIX.

Теперь вы можете перейти к разделу "Трансляция команд из DOS в Linux", но на вашем месте я бы прочитал

## 3.2. Символические связи

UNIX имеет тип файла, который не существует под DOS - это символическая связь. О нем можно думать как о указателе на файл или каталог, и можно использовать вместо файла или каталога, на который он указывает; он напоминает шорткаты Windows 95. Примеры символических связей - `/usr/X11`, который указывает на `/usr/X11R6`; `/dev/modem`, который указывает или на `/dev/cua0` или `/dev/cua1`.

Чтобы создать символическую связь используется команда `ln`:

> `

>            $ ln -s <file_or_dir> <linkname>

> `

Пример:

> `

>            $ ln -s /usr/doc/g77/DOC g77manual.txt

> `

Теперь Вы можете обращаться к `g77manual.txt` вместо `/usr/doc/g77/DOC`. Связи в распечатках каталога показываются так:

> `

>            $ ls -F

>            g77manual.txt@

>            $ ls -l

>            (...)           g77manual.txt -> /usr/doc/g77/DOC

> `

## 3.3. Права доступа и владение

Файлы DOS и каталоги имеют следующие атрибуты: A(архив), H(скрытый), R(только для чтения), и S(системный). Только H и R имеют смысл в Linux: невидимые файлы начинаются с точки, а R - атрибут чтения.

Под UNIX файл имеет "права доступа" и владельца, который в свою очередь принадлежит "группе". Рассмотрите этот пример:

> `

>            $ ls -l /bin/ls

>            -rwxr-xr-x  1  root  bin  27281 Aug 15 1995 /bin/ls*

> `

Первое поле содержит права доступа к файлу `/bin/ls`, который принадлежит root, группы bin. Отставляя пока остальную информацию в сторонку, запомните что означает `-rwxr-xr-x`, слева направо:

`-` тип файла (`-` = обычный файл, `d` = каталог, `l` = линк, и т.д); `rwx` - права доступа для владельца файла (чтение, запись, выполнение); `r-x` - права доступа для группы владельца файла (чтение, выполнение); (я не буду освещать понятие группы; пока Вы - новичок, Вы можете прожить и без этого ;-) `r-x` - права доступа для всех других пользователей (чтение, выполнение).

каталог `/bin` тоже имеет права доступа: см. Раздел "Права доступа каталогов" для дальнейших подробностей. Это - та причина, по которой Вы не можете удалить файл `/bin/ls`, если Вы не root: Вы не имеете прав на эти действия. Для изменения прав доступа к файлу используется команда:

> `

>            $ chmod <whoXperm> <file>

> `

где, `who` - это `u`(пользователь-владелец), `g`(группа), `o`(другие), `x` может быть или `+`, или `-`, `perm` - это `r`(чтение), `w`(запись) или `x`(выполнение). Общие примеры использования `chmod` - следующие:

> `

>            $ chmod +x file

> `

Установка для файла прав на выполнение.

> `

>            $ chmod go-rw file

> `

Удаление прав на чтение и запись для всех, кроме владельца.

> `

>            $ chmod ugo+rwx file

> `

Все могут читать, писать в и выполнять файл.

> `

>            # chmod +s file

> `

Это действие создает так называемый ``setuid'' или ``suid'' файл --- файл, который любой пользователь может выполнять с правами владельца этого файла. Обычно, вы встретитесь с root suid файлами; они часто являются важными системными файлами, например, X сервер.

Более короткий способ обращения к правам доступа - цифрами: `rwxr-xr-x` может быть выражен числом, поскольку 755 (каждый символ соответствует биту: `---` - это 0, `--x` - это 1, `-w-` - это 2, `-wx` - это 3 ...). Это выглядит сложновато, но, практикуясь, вы поймете эту концепцию. Root, являясь суперпользователем, может изменять любые права доступа к файлам. RMP.

## 3.4. Файлы: Трансляция команд

Слева команды DOS; справа их синонимы Linux .

> `

>            ATTRIB:         chmod

>            COPY:           cp

>            DEL:            rm

>            MOVE:           mv

>            REN:            mv

>            TYPE:           more, less, cat

> `

Операторы перенаправления ввода-вывода: `< >> > |`

Маски имен файлов: `* ?`

`nul: /dev/null`

`prn, lpt1: /dev/lp0 or /dev/lp1; lpr`

### Примеры

> `

>            DOS                                     Linux

>            ---------------------------------------------------------------------

>            C:\GUIDO>ATTRIB +R FILE.TXT            $ chmod 400 file.txt

>            C:\GUIDO>COPY JOE.TXT JOE.DOC          $ cp joe.txt joe.doc

>            C:\GUIDO>COPY *.* TOTAL                $ cat * > total

>            C:\GUIDO>COPY FRACTALS.DOC PRN         $ lpr fractals.doc

>            C:\GUIDO>DEL TEMP                      $ rm temp

>            C:\GUIDO>DEL *.BAK                     $ rm *~

>            C:\GUIDO>MOVE PAPER.TXT TMP\           $ mv paper.txt tmp/

>            C:\GUIDO>REN PAPER.TXT PAPER.ASC       $ mv paper.txt paper.asc

>            C:\GUIDO>PRINT LETTER.TXT              $ lpr letter.txt

>            C:\GUIDO>TYPE LETTER.TXT               $ more letter.txt

>            C:\GUIDO>TYPE LETTER.TXT               $ less letter.txt

>            C:\GUIDO>TYPE LETTER.TXT > NUL         $ cat letter.txt > /dev/null

>                    n/a                            $ more *.txt *.asc

>                    n/a                            $ cat section*.txt | less

> `

Примечания:

- `*` является более сильной под Linux: `*` соответствует всем файлам за исключением скрытых; `.*` соответствует всем невидимым файлам (но также и текущему каталогу "`.`" и каталогу предыдущего уровня "`..`": будьте осторожны!); `*.*` соответствует только тем файлам, которые имеют "`.`" в середине или конце; `p*r` соответствует и "`peter`", и "`piper`"; `*c*` соответствует, и "`picked`" и "`peck`";
- при использовании `more`, нажмите ПРОБЕЛ, чтобы продолжить чтение файла, "q" чтобы выйти. `less` более интуитивен и позволяет Вам использовать клавиши курсора;
- перед удалением файла дважды подумайте, потому что команды UNDELETE нет;
- в добавление к операторам DOS'а `< > >>`, Linux имеет `2>` для перенаправления сообщений об ошибках (`stderr`); кроме того, `2>&1` перенаправит `stderr` в `stdout`, в то время как `1>&2` перенаправит `stdout` в `stderr`;
- в Linux есть еще одна маска для файлов: `[]`. Использование: `[abc]*` выберет файлы начинающиеся с `a, b, c`; `*[I-N1-3]` выберет файлы, заканчивающиеся на `I, J, K, L, M, N, 1, 2, 3`;
- `lpr <file>` печатает файл в фоновом режиме. Для проверки статуса очереди печати, используйте `lpq`; чтобы удалить файл из очереди печати, используйте `lprm`;
- команда вроде DOSовского `RENAME` отсутствует; то есть `mv *.xxx* .yyy` не будет работать. Вы можете попробовать этот простой скрипт; см. раздел ``Скрипты shell: .BAT файлы, объевшиеся стероидов'' для подробностей.

           #!/bin/sh

           # ren: rename multiple files according to several rules

           if [ $# -lt 3 ] ; then

             echo "usage: ren \"pattern\" \"replacement\" files..."

             exit 1

           fi

           OLD=$1 ; NEW=$2 ; shift ; shift

           for file in $*

           do

             new=`echo ${file} | sed s/${OLD}/${NEW}/g`

             mv ${file} $new

           done

  Осторожно: он не соответствует DOSовскому `REN`, поскольку использует "регулярные выражения", который Вы все еще не знаете. Короче, если Вы просто хотите изменять расширения файла, используйте его так: `ren "htm$" "html" *htm`. Не забудьте знак `$`.
- чтобы получать предупреждения перед попыткой перезаписи файла, используйте `cp -i и mv -i`

## 3.5. Запуск программ: многозадачный режим и сеансы

Чтобы выполнить программу, напечатайте имя, также как это делается под DOS. Если каталог (раздел "Использование Каталогов''), в котором находится программа, включен в PATH (раздел "Файлы инициализации системы''), то программа запустится. Исключение: в отличие от DOS, под Linux программа, расположенная в текущем каталоге не запустится, если этот каталог не включен в `PATH`. Выход из этой ситуации: если программа называется `prog`, напечатайте `./prog`.

Вот как выглядит типичная командная строка:

> `

>       $ command [-s1 [-s2] ... [-sn]] [par1 [par2] ... [parn]] [< input] [> output]

> `

где `-s1, ..., -sn` - ключи программы, `par1, ..., parn` - параметры программы. Вы можете поместить несколько команд в одной строке:

> `

>            $ command1 ; command2 ; ... ; commandn

> `

Это все о запуске программ, но это просто небольшой шаг в этом вопросе. Одна из основных причин использования Linux - то, что он является многозадачной ОС - может выполнять несколько программ (будем называть их процессами) одновременно. Вы можете запустить процессы в фоновом режиме и продолжить работать дальше. Кроме того, Linux позволяет Вам запускать несколько сеансов: это похоже на одновременную работу на нескольких компьютерах!

- чтобы переключиться между сеансами 1..6 на виртуальных консолях, нажмите соответственно <ALT-F1> ... <ALT-F6>
- чтоб начать новый сеанс на той же самой виртуальной консоли (vc) без выхода из текущего сеанса, напечатайте `su - <loginname>`. Пример: `su - root`. Это полезно, например, когда Вы должны выполнить задачу, для которой требуются права root
- чтобы закончить сеанс, напечатайте `exit`. Если имеются остановленные работы (см. далее), то вы получите предупреждение.
- чтобы запустить процесс в фоновом режиме, добавьте символ & в конце командной строки:

  > `

  >            $ progname [-switches] [parameters] [< input] [> output] &

  >            [1] 123

  > `

  shell идентифицирует процесс номером работы (например `[1]`; см. ниже) и PID (Идентификационным Номером Процесса); в нашем примере 123).
- чтобы посмотреть, какие процессы запущены, напечатайте `ps -ax`, и вы увидите список запущенных процессов.
- чтобы уничтожить процесс, напечатайте, `kill <PID>`. Вы может понадобиться прибить процесс, когда Вы не знаете, как правильно выйти из него .... Если вы не root, то Вы не можете уничтожать процессы других людей. Иногда, процесс уничтожатется только с помощью `kill -SIGKILL <PID>`.

  Кроме того, shell позволяет Вам останавливать или временно приостанавливать процесс, переводить процесс в фоновый режим и переводить процесс из фонового режима в активный режим. В этом контексте, процессы называются "работами".

- чтобы узнать количество работ, напечатайте `jobs`. Здесь работы идентифицированы своими номерами работы, а не их PID.
- чтобы остановить процесс, протекающий в активном режиме, нажмите <CTRL-C> (это не всегда срабатывает).
- чтобы приостановить процесс, протекающий в активном режиме, нажмите <CTRL-Z> (тоже самое).
- чтобы перевести приостановленный процесс в фоновый режим, напечатайте bg <работа> (он становится работой).
- чтобы перевести работу в активный режим, напечатайте fg <работа>. Чтобы перевести в активный режим последнюю переведенную в фоновый режим работу, просто напечатайте `fg`.
- чтобы уничтожить работу, напечатайте `kill <%работа>`, где <работа> может быть 1, 2, 3, ...

Используя эти команды, Вы можете форматировать диск, паковать насколько файлов, компилировать программу и распаковывать архив одновременно и все еще иметь командную строку в вашем распоряжении. Пробуйте это сделать в DOS! И посмотрите как это будет работать в Windows, чтобы увидеть различие в эффективности (если Windows не упадет, конечно).

## 3.6. Запуск программ на удаленных компьютерах

Чтобы запустить программу на удаленной машине, чей IP адрес - `remote.machine.edu`, выполните:

> `

>            $ telnet remote.machine.edu

> `

После регистрации на удаленной машине, запустите вашу любимую программу. Само собой разумеется, Вы должны иметь доступ к shell на удаленной машине.

Если у Вас установлен X11, то Вы можете даже запустить X приложение на удаленном компьютере, отображаая его на вашем X экране. Допустим, что `remote.machine.edu` - это удаленный X компьютер, а `local.linux.box` - это ваша Linux машина. Чтобы запустить с `local.linux.box` программу X, которая расположена на `remote.machine.edu`, сделайте следующее:

- запустите X11, запустите `xterm` или эквивалентный эмулятор терминала, затем напечатайте:

  > `

  >            $ xhost +remote.machine.edu

  >            $ telnet remote.machine.edu

  > `

- После регистрации, напечатайте:

  > `

  >            remote:$ DISPLAY=local.linux.box:0.0

  >            remote:$ progname &

  > `

  (вместо `DISPLAY`..., вам может надо будет написать: `setenv DISPLAY local.linux.box:0.0`. Это зависит от удаленного shell.)

Вуаля! Теперь progname запустится на `remote.machine.edu` и будет отображаться на вашей машине. Не пробуйте это на модемных соединениях, такая связь слишком медленна, чтобы быть пригодной для использования.