Несколько основных команд в Linux 1.3

Взаимодействие с оболочкой
Теперь, когда освещены основные команды и в руках есть инструменты, начнут возникать вопросы типа: а как мне то совместить с этим? А как мне отменить действие того? А как...? То есть, требуется осветить ухищрения и дополнения, касающиеся взаимодействия именно пользователя с консолью, оболочкой.
Чтобы прервать действие текущей команды и выгрузить её к чертям, нажмите Ctrl+C
Если Вы хотите только заморозить её на время, нажать паузу - нажмите Ctrl+Z
Чтобы вернуть процессу жизнь - напишите fg и нажмите Enter. Вы вернули процесс на foreground (передний план)
Если вы хотите, чтобы процесс работал на заднем фоне, а вам отдал приглашение для дальнейшей работы, вместо fg укажите bg - и он уйдёт на background - задний план.
Кроме того, можно сразу запустить процесс на задний план - для этого в конце строки всего лишь надо добавить символ &
Например: cp -r * /mnt/hda6/ & Начнёт на заднем фоне копирование, а вам вернёт приглашение для работы и номер процесса копирования (PID).
Можно выполнить команды последовательно одну за другой, разделив их знаком точки с запятой,
Например: cp -r * /mnt/hda6 ; /sbin/poweroff Скопирует все файлы в каталог, а затем выключит компьютер.
Можно быстро автоматизировать контроль над выполнением программы - например, в случае удачного завершения какого-либо действия выполнить одну команду, а в случае неудачи - другую:
copy * /mnt/hda6 && /sbin/poweroff || echo "ERROR!" - как видно на примере, разделительные символы между командами характеризуют удачность выполнения команд. Хитрость в определении удачности кроется в возвращаемом цифровом коде выхода программы. Если не произошла ошибка во время выполнения, команда возвращает 0, иначе число больше 0.

Простые циклы и постановка условий
Для построения разного рода смысловых схем из программ полезно использовать циклы и условия. Это является основой всех программ. Это полезно в малых дозах и при обычной работе с системой. Например так:


for i in *
do
if [ -d $i ]
then
echo "Directory: $i"
elif [ -L $i ]
then
echo "Symlink: $i"
else
echo "File: $i"
fi
done

То же самое можно написать в одну строчку:

for i in *; do if [ -d $i ];then echo "Directory: $i"; elif [ -L $i ];then echo "Symlink: $i"; else echo "File: $i"; fi;done

Здесь квадратные кавычки являются завуалированной командой test. Это или программа, или команда оболочки, подробнее о её параметрах можно узнать через man test или man sh.

Как писать простые скрипты
Скрипты - текстовые файлы с битом исполняемости или без. В заголовке (первые байты) имеют сигнатуру запуска с помощью программы-интерпретатора. Эта сигнатура состоит из двух символов "#!", после которых идёт путь к программе-интерпретатору. Например, заголовок скрипта, который исполняется программой-оболочкой:
#!/bin/sh
Если запустить файл, содержащий это в самом начале, на выполнение, то запустится новый процесс sh, на вход которого будут переданы все команды, находящиеся в теле скрипта. Это удобнее тем, что команды можно писать не в одну строку, а в развёрнутом виде и с возможностью удобного редактирования, повторного применения. Есть два варианта выполнения уже написанного скрипта - либо дать ему бит исполняемости и запустить непосредственно из командной строки, либо дать его в качестве параметра требуемому интерпретатору, вот так:
1 Вариант:


chmod +x filename.sh
./filename.sh

2 Вариант:


sh filename.sh


Чисто системные вещи

Как узнать, в какой конкретно системе я нахожусь?
Первое движение - наберите команду:
uname -a
Это сообщит версию ядра, тип системы, время компиляции, тип железа.
Затем, в большинстве дистрибутивов в каталоге /etc находится файл блаблабла-release или блаблабла_version, где блаблабла - что-то близкое к названию дистрибутива.
Узнать наличие можно так:
ls /etc/*(release,version)
Затем вывести на экран содержимое подходящих среди найденного файлов:
cat /etc/debian_version
Это более подробно расскажет о дистрибутиве.

Что такое переменные среды и как их использовать?
Переменные среды - это контейнеры в памяти оболочки (shell, консоль) для содержания настроек. Полный их список можно посмотреть командой
set
Некоторые меняются автоматически, остальные довольно статичны. Они используются программами для более корректной работы в среде. Каждая программа (вернее, процесс) получает слепок значений этих переменных на момент запуска и затем пользуется ими до конца своей работы. То есть, если вы обновили какие-либо переменные и хотите, чтобы об этом узнали уже запущенные процессы, их придётся перезапустить. Но, в отличие от Windows, где изменение переменных среды в консоли сразу применяется в среде в целом, в Unix изменение переменных может наследоваться лишь текущим или дочерним процессом, относительно того, который совершил изменение переменной. Образно говоря, если на дереве процессов одна ветвь изменила свой слепок переменных, то этот слепок будет использоваться лишь ею и её дочерними ветвями переменных. Изменение не применится к любому вновь созданному процессу, родителем которого стала другая консоль (tty)! Вот почему в ряде случаев приходится перезапускать X-сервер или другие, серверные процессы.
Изменить переменные можно простой операцией присваивания:
имя_переменной=значение (Внимание - пробелы недопустимы. Если в строке значения есть пробелы, нужно взять всё значение в кавычки.)
Таким образом новое значение переменной будет в дальнейшем использоваться этим процессом. Для того, чтобы это значение наследовали все вновь созданные дочерние процессы, нужно экспортировать переменную для потомков:
export имя_переменной
Во многих оболочках, например, bash, zsh - можно объединить эти две команды в одну:
export имя_переменной=значение
Можно использовать значения переменных в своих командах и скриптах. Для этого перед именем переменной нужно поставить знак бакса.

echo $SHELL
/bin/zsh

В переменных хранится многое - например, форма вашего приглашения командной строки:
echo $PS1
Самая важная - это, безусловно, PATH. Содержит в себе пути, разделённые через двоеточие, в которых ищется набранная вами команда. У root-а в PATH кроме стандартных путей, присутствуют пути /sbin и /usr/sbin, где лежат команды, которыми обычно пользуется только root.

Что такое кодировка и как её посмотреть/поменять
Кодировка - это название порядка, в котором расположены все символы в шрифте. Для показа текста программы используют шрифты. Шрифт может поддерживать одну или более кодировок. Есть такие термины, как текущая кодировка, системная кодировка, кодировка по умолчанию. То есть существует переменная, содержащая в себе название кодировки. Её можно менять как глобально, так и для каждого приложения на время работы. Посмотреть все переменные, относящиеся к кодировке, можно командой:
locale
Изменить достаточно просто, например:
export LANG=ru_RU.CP1251 Таким образом меняем кодировку на cp1251.
В большинстве современных дистрибутивов кодировка по умолчанию UTF8 (юникод, содержащий в себе сразу все известные символы). Другие кодировки обычно содержат в себе кроме латинских символов ограниченные наборы других букв для разных языков. Предыдущим стандартом де-факто для русскоязычных дистрибутивов была кодировка KOI8-R. Многие консольные программы привязываются к значениям переменных, перечисленных в locale и выводят свои сообщения и другую информацию на языке, который указан перед кодировкой. К примеру, если у вас переменная LANG равна en_EN.что-то ещё, программы предпочтут общаться с вами по-английски, даже если имеют множество переводов в запасе. Также текущая кодировка влияет на отображение имён файлов, находящихся на разделах и подключенных сетевых ресурсах. См. команду mount. Ранее проблема русификации и борьбы с кодировками была актуальной, но примерно с 2003-2004 года ситуация значительно изменилась к лучшему и проблем почти нет.

монтирование файловых систем
Для многих это заметная часть работы с linux со множеством подробностей и путей решения.
Как уже говорилось выше, для монтирования необходимы два объекта - блочное устройство (в /dev/) и какая-либо директория, желательно пустая (точка монтирования), в которую будет монтироваться это устройство. В системе есть файл /etc/fstab, в котором прописаны все статичные точки и объекты монтирования. Его синтаксис довольно прост:
устройство точка_монтирования файловая_система параметры_монтирования бит_критичности бит_проверки
Если устройство уже указано в этом файле, его можно монтировать без указания параметров:
mount /dev/устройство
Если же устройство там не указано, то в большинстве случаев смонтировать его может только root и при этом как минимум придётся указывать точку монтирования. Если для указанного в fstab устройства в параметрах есть опция users, любые пользователи смогут смонтировать и размонтировать указанное устройство. Не получится размонтировать устройство, примонтированное другим пользователем. Оно и логично. Параметры монтирования сильно зависят от файловой системы, под котору отформатировано устройство. Кроме того, в системе есть файл /etc/mtab, в котором перечислены все уже смонтированные устройства и указаны все параметры, которые были применены при монтировании. Его аналог в виртуальной системе /proc - файл /proc/mounts. Также полезен файл /proc/partitions для изучения присутствующих в системе блочных устройств. К примеру, если вы воткнёте флешку, в /proc/partitions добавится одна-две строки с указанием имени устройства и размера раздела (партиции) флешки.
Смонтировать удастся только те разделы, которые отформатированы в доступные этому ядру файловые системы. Список доступных файловых систем перечислен в /proc/filesystems. Изменить этот список можно перекомпиляцией ядра (см. ниже).
Пример монтирования флешки с файловой системой FAT32 и файлами с русскими именами, созданными под Windows (типичная ситуация):
mount /dev/sda1 /mnt/sda1 -t vfat -o codepage=866,iocharset=koi8-r
iocharset указывает на текущую локаль (см. выше - кодировка). Указывать тип файловой системы необязательно - mount обычно правильно определяет сам.
запись для быстрого монтирования в fstab:
/dev/sda1 /mnt/sda1 vfat noauto,users,uid=username,gid=groupname,codepage=866,iocharset=koi8-r 0 0
Параметр noauto говорит о том, что монтирование будет произведено вручную, а не при старте системы.
То же самое для ресурса samba:
mount //servername/sharename /mnt/samba_share -t smbfs -o username=user_name/domain_name,ip=IP,codepage=cp866,iocharset=utf8
//servername/sharename /mnt/samba_share smbfs noauto,users,username=user_name/domain_name,ip=IP,codepage=cp866,iocharset=utf8 0 0
Если вы сами скомпиляли ядро с указанием правильной codepage и пр. - указывать эти параметры не нужно.
Кроме реальных файловых систем и сетевых шар, в /etc/fstab обычно прописывается некоторое количество виртуальных fs, нужных для функционирования системы, а также разделы подкачки (да, да - Вы не ошиблись - разделов, а не файлов. Разделов, у которых нет фрагментации ). Конечно, можно подкачку сделать и файлом... Здесь вообще возможно всё. Например, смонтировать ISO-образ, как папку:
mount /mnt/image_cd.iso /mnt/iso -o loop
По-моему, до этого никогда не дорастёт Windows в силу избыточности абстракционных прокладок между юзером и системой.
Кстати, можно создать файл, отформатировать его и подключить, как раздел. Вот три строчки:
dd if=/dev/zero of=filename.ext bs=1048576 count=размер_в_мегабайтах
mkfs.ext3 ./filename.ext
mount ./filename.ext /mnt/some_directory -o loop
Можно также ещё и зашифровать его, но тут полезно бы почитать материальчики в гугле. В принципе, всё просто.
Касательно новых систем. Файл /etc/fstab был удобной штукой, но не совсем. Пока root явно не разрешит - ничего не смонтировать. В свете распространения кучи съёмных носителей, фотоаппаратов, прописывать всякие строчки в fstab стало мучением. Придумано много вариантов, с HAL, например. В итоге, в момент появления флешки в системе, запускается тот или иной скрипт, автоматом монтирующий её в только что созданную поддиректорию в /media. Обычно название директории равно её лейблу или носит название типа носителя, например, usbdisk. А вот с размонтированием посложнее. Да и с указанием дополнительных параметров (например, локализации) придётся попариться. Мож я и варвар, но если не используется pmount (debian-системы), то я делаю sync и просто вытаскиваю флешку. Системная команда sync делает одноимённый системный вызов и сбрасывает все несохранённые данные в кэшах дисков на носители (чтобы не осталось ничего недописанного), а факт отсутствия носителя обычно размонтирует его. Утилита pmount позволяет монтировать/размонтировать съёмные носители под обычными пользователями, пользуясь полномочиями root-а.
Например, так:
pumount /dev/sda1
Не пытайтесь найти её установленной. Такие системы как suse, mandrake, redhat - просто синхронизируют fstab перед монтированием съёмных носителей и ограничиваются командой mount.

Как запустить сервис?
Сервис в linux - это не более, чем обычный бинарник, запущенный при старте системы. Для удобства вокруг каждого такого бинарника "оплетён" скрипт, который его запускает и останавливает с разными параметрами командной строки, следит за его ID-шником и так далее. Исходя из этого, легко создать свой "сервис", который запускается при старте. Обычно все эти скрипты хранятся в каталоге /etc/init.d. Не все скрипты, которые находятся в этом каталоге, запускаются при старте системы. У системы при запуске есть несколько уровней (вариантов запуска) на выбор. Каждый уровень определяет, какие сервисы будут загружены при старте. Уровни представляют собой каталоги с симлинками на нужные сервисы и при запуске определённого уровня просто происходит запуск всех симлинков в определённом каталоге. Т.е., всё примитивно и просто. Каталоги уровней выглядят обычно так: /etc/rcN.d (почти все линуксы) или /etc/rc.d/rcN.d (redhat-suse), где N - это номер уровня. Кроме того, есть три специальных уровня - S, 0 и 6, которые являются начальной (необходимой) загрузкой, уровнем выключения и уровнем перезагрузки. Дело в том, что при запуске все скрипты-сервисы запускаются с параметром start, а при останове - с параметром stop. Поэтому почти все сервисы, симлинки на которые находятся в уровнях 0 и 6, запускаются с параметром stop, что приводит к корректному выключению всех служб.
Указатель уровня загрузки по умолчанию указан в файле /etc/inittab и выглядит так:

id:3:initdefault:

где 3 - уровень загрузки системы по умолчанию. Всё это вместе (симлинки, скрипты сервисов и прочее) называется стандартом SystemV. Есть ещё BSD-стандарт загрузки, он применяется в Linux Slackware и BSD-юниксах - там нет симлинков и директорий, а все действия по загрузке прописаны в единственном скрипте.

Примеры:
/etc/rc6.d/K20samba Симлинк останова сервиса samba при перезагрузке.
/tc/rcS.d/S40networking Симлинк поднятия сетевых интерфейсов при начальном старте системы.
/etc/rc2.d/S15ejabberd Симлинк поднятия службы EJABBERD при старте во втором уровне.
Использование:
init 5 Переключиться на уровень 5. Доступно только root-у.
init 0 Выключить систему.
init 6 Перезагрузить систему
/etc/init.d/ssh restart Перезагрузить сервис ssh
/etc/init.d/inetd start Запустить сервис inetd
Кстати, в Unix-системах существует интересный сервис inetd (или xinetd) - его народное название "суперсервис". Он существенно облегчает нагрузку на систему в случае кучи поднятых служб - в результате реально в памяти висит его единственный процесс и прослушивает кучу сетевых портов, которые закреплены за подвластными ему службами. В момент обращения на какой-либо порт извне, inetd быстро запускает процесс службы и передаёт ему соединение. Это оправданно при редких соединениях и большом количестве служб. Его конфигурация хранится в /etc/inetd.conf или /etc/xinetd.d

Установка программ
#TODO:

Что делать, если не найдена в линуксе моя железяка?
Для начала взять свежую версию ядра и скомпилять его, поискав в перечне драйверов свою железяку.

Как скомпилять ядро?
Итак, ядро - это файл vmlinuz-version в папке /boot, где version - номер в цифирках. Кроме того, типично в папке /lib/modules/version хранится энное количество файлов модулей (драйверов). Почти все драйвера можно воткнуть или в само ядро или вынести отдельно в эту папку в виде файла. То есть, получается три состояния какого-либо отдельного драйвера - не скомпилян вообще, скомпилян в виде модуля, вкомпилян в ядро намертво. Преимущество модулей перед вариантом вкомпилирования в ядро в том, что их можно загружать и выгружать по необходимости, а вкомпилянные намертво грузятся при старте ядра и висят в памяти всегда. Существуют и монолитные ядра - в них всё, что необходимо - вкомпиляно прямо в ядро, а поддержка модулей вырублена вообще. Это применяют на боевых защищённых системах, чтобы исключить шанс загрузки самодельного модуля злоумышленником. Кроме драйверных модулей в ядре есть много другого кода, отвечающего за логику работы системы и прочие фишки.
Также существует такая вещь, как initrd - это такой сжатый образ раздела, содержащий дополнительные модули ко всяким хитрым скази-контроллерам и редкоиспользуемым файловым системам, который подменяет при самом старте ядра реальный корень и используется лишь до тех пор, пока в нём существует необходимость. Когда же все необходимые модули с него были использованы, то ядро опять цепляет вместо него реальный корневой раздел. Это своего рода костыль, но он широко применяется во всех дистрибутивах, потому что заранее неизвестно, какое железо окажется у клиента, а всю дрянь подряд прямо в ядро компилять некультурно. Для поддержки этого режима (загрузки с помощью initrd) во всех загрузчиках даже есть отдельная опция - initrd с параметром пути к файлу. Повторюсь, что initrd - это такой сжатый файл с образом диска внутри, где есть всякие левые модули. Т.е., ничего принципиально нового. Используется лишь тогда, когда ядро имеет шанс не достучаться до реального корневого раздела из-за отсутствия необходимых модулей (драйверов). Если же компилять собственное ядро под определённое железо, то initrd не нужен в принципе и только жрёт лишнее место-память.
Далее. В большинстве дистрибутивов ядра по умолчанию идут с максимальным включением всех драйверов, имеющихся в той версии ядра, которое будет в составе дистрибутива. Ну, чтобы на всём железе загрузилось. Поэтому, когда возникает ситуация, что что-то не работает, то первое, что надо сделать - это скачать наираспоследнейшую версию ядра и прокомпилять её, указав только то железо в настройках, которое у Тебя есть. Выборочная, а не тотальная компиляция всех фич ядра сильно экономит время и немного экономит дисковое пространство. Скачивать последнюю версию ядра (исходники) надо с ftp://ftp.kernel.org,
там много веток, но стабильные (нужные) - лишь те, которые чётные. Типа 2.0, 2.2, 2.4, 2.6... Конкретный файл будет иметь больше цифирок в версии, например, 2.6.15.16 Скачивать лучше тот файл, который имеет меньший вес. Т.к. там одна и та же версия сразу сжата в как минимум, два типа архиватора - gz (меньшее сжатие) и bzip2 (bz - большее сжатие, но распаковщик есть не на всех дистрибутивах). Кроме того, есть файлы с хешем, размер несколько байт (для проверки корректности скачивания). Общий расклад размеров таков:
Сжатый исходник ядра - 30-50 Мбайт
Распакованный исходник ядра - 300-500 Мбайт
Скомпилянное ядро с модулями - 1 - 50 Мбайт
Распаковывать просто - через:
tar xjf linux-XXXXXX.tgz
Помещать распакованное ядро рекомендуется, но не обязательно, в папку /usr/src. Т.е., скачиваем, заходим под рутом в папку /usr/src и уже оттуда делаем распаковку:


$ wget ftp://ftp.kernel.org/pub/linux/v2.6/linux-2.6.18.tbz
$ su -
Password:
# cd /usr/src
# tar xjf /home/username/linux-2.6.18.tbz
# ln -s linux-2.6.18 linux
# cd linux
# make menuconfig


Только версия, конечно, может отличаться.
Если при запуске в каталоге с распакованным ядром make menuconfig выводятся ошибки - скорее всего, отсутствуют пакеты компиляторов (gcc, make и проч.).
Что именно выбирать дальше - это отдельная история. Если вы собираетесь скомпилировать без поддержки initrd, то в Filesystems вам необходимо выбрать не модулем [M], а внутрь ядра [*] ту файловую систему, под которую отформатирован ваш корневой (/) раздел (см. через mount). Кроме того, внимательно смотрим спецификацию железа и точно таким же образом ([*]) компилируем драйвер к своему IDE/SATA/SCSI/USB-контроллеру, через который подключен ваш винт с корневым разделом.
После того, как вы определились с нужными драйверами, выходите с сохранением файла конфигурации (имя файла будет .config, увидеть можно через ls -a) и набирайте такое заклинание:
make bzImage && make modules && make modules_install && make install
Затем может понадобиться внести новые записи в /boot/grub/menu.lst (если у вас загрузчик grub) или в /etc/lilo.conf (если у вас lilo - для него, кстати, ещё необходимо запустить команду lilo)
Всё это в принципе несложные вещи, главное, понимать, что делаешь в каждый момент времени. Фактически Вы сформируете новый файл ядра, о котором должен знать загрузчик, а также получите набор указанных Вами модулей в каталое /lib/modules. Затем перезагрузка и выбор вашего пункта в загрузчике. Т.е. загрузится тот же самый Ваш линукс, только с другим ядром. Старое ядро тоже останется на всякий случай.
Насколько я знаю, с первого раза почти ни у кого не получается скомпилировать ядро удачно. Это как конструктор Lego - получится обязательно, но после того, как вы осознаете роль каждой детали в схеме...

Чем консоль лучше mc?
Midnight Commander - популярный файл-менеджер с двумя панелями, клон far и Norton Commander для Unix-а. Популярность его основана на том, что наглядность работы с ним лежит на поверхности и не нужно ничего изучать, чтобы начать с ним работать. К сожалению, на этом все достоинства этой программы заканчиваются. Наглядность работы в консоли можно довести до уровня MC и даже больше - советую посмотреть на ZSH. Для этого достаточно нескольких строк настроек в профиле пользователя. А вот по части безглючности и гибкости - тут MC явный аутсайдер. Да и по части логичной автоматичности - далеко не удачный выбор. Скажем, простейшая операция - я хочу скопировать рекурсивно содержимое одной директории в другую. Для этого мне в одной панели нужно встать на директорию, откуда я собираюсь скопировать объекты, а в другой - куда. Щелчков и ударов по клавишам для этого придётся выполнить немало, ну да ладно. В консоли мне придётся написать это:
cp -r /from /to
Следует учесть, что пути к директориям в консоли добиваются [tab]-ами, т.е., набор минимален и в принципе сравним с количеством нажатий клавиш в варианте с MC.
Теперь начнём копировать. По идее, MC гораздо нагляднее - выводит скорость копирования, процент завершения, время до конца копирования, имена копируемых файлов и всё такое... Хм. Всё это наглядно лишь в том случае, если вы собираетесь наблюдать за этим процессом. Обычно, если процесс будет быстротечным, смотреть на это нет смысла. Если же очень долгим - то же самое. Лишь изредка смотреть - завершилось или нет.
А что касается возможных ошибок чтения-записи? По умолчанию MC остановится и затормозит процесс копирования после первой ошибки доступа. Т.е., приходим мы через час, а там - 1% выполнения. Смешно? Хорошо, будем справедливы - в настройках можно выставить игнорирование ошибок - тогда процесс будет продолжаться непрерывно. А где же список ошибок?, спросите вы. Опаньки, приехали.
Спрашивается, зачем мучать ж, когда всё это из коробки будет в консоли? И лог ошибок, и чтение-запись без остановки и уровень подробности и флаги перемещения. Это всё при примерно одинаковом уровне сложности набора.
Тот, кто имеет довод типа "Если надо скопировать некоторые файлы, то я замучаюсь их все писать в одну строку в консоли", скорее всего незнаком ни с ZSH, ни с регулярными выражениями. Ибо выбирать в консоли можно как стрелками, так и буквами и даже спецсимволами и регулярными выражениями.
Обратная сторона медали сомнительной наглядности кроется в торможении изучения системы - очень часто люди, подсевшие на MC, начинают спрашивать меня - как сделать то или это, что выходит за рамки его функционала, либо нудно делают монотонные действия в MC, могущие решить проблему... Зачем?? Лишь бы не напрягать голову. Помнится, в составе Redhat Enterprise нет mc. Сколько было криков по этому поводу! Прямо-таки невозможно работать.

Комментариев нет:

Отправить комментарий