20 июл. 2000 г.

Книги по Linux

источник

1Linux GeneralLinux General
Книги о Linux на английском языке

2Direct Books LinuxDirect Books Linux
Раздел Linux, книги на русском языке

3E-booksE-books
Категория Linux, гайды на английском языке

4Linux books USLinux books US
Библиотека Linux-книг на английском языке





5Бесплатные IT-книгиБесплатные IT-книги
Хорошая подборка it-литературы, в том числе и по linux

6Линукс по-русскиЛинукс по-русски
Библиотека русских книг сайта linux-rus.net

7LinuxlandLinuxland
Книги по Linux на русском языке

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

9БЕСПЛАТНЫЙ базовый курс UbuntuБЕСПЛАТНЫЙ базовый курс Ubuntu
Это электронная книга, в которой описан процесс установки и настройки Ubuntu Linux.

10Knigka.infoKnigka.info
Раздел Linux. Бесплатные книги

11Книги и учебники от AltLinux Книги и учебники от AltLinux
Хорошие платные книги

12ЛинуксцентрЛинуксцентр
Библиотека Линуксцентра

13Linux.brestautoLinux.brestauto
Каталог книг от Linux.brestauto

14OpennetOpennet
Архив документации от Opennet

15Переводы страниц руководства manПереводы страниц руководства man
Переводы внутренних руководств ОС Linux, благодарим авторов за тяжкий и кропотливый труд

16Компьютерное издательство ДиалектикаКомпьютерное издательство Диалектика
Набор русскоязычных изданий о Linux

17Programmers KlondikeProgrammers Klondike
Бесплатные книги о Linux

18Fossbook от alv'aFossbook от alv'a
OSSBook — онлайновая книга о мире открытого и свободного софта во всех его проявлениях

19LinuxOpenLinuxOpen
Библиотека портала LinuxOpen, хорошая подборка

20Ubuntu Pocket Guide and ReferenceUbuntu Pocket Guide and Reference
Бесплатный справочник по Ubuntu на английском языке

21HELLOWORDHELLOWORD
HELLOWORLD.RU - документация и книги по программированию, в т.ч. Web и Linux.

22Компьютерная литератураКомпьютерная литература
Администрирование, компьютерная литература, книги по администрированию, Linux Windows.

23All-eBooks.comAll-eBooks.com
Электронная литература, раздел Linux.





24Linux-book.ruLinux-book.ru
Подборка книг о *nix и Linux системах.

Vim шпаргалка по основным коммандам

Режимы работы

Существует три основных режима работы: режим команд, режим редактирования и режим последней строки. Выход из режима редактирования осуществляется клавишей Escape (далее обозначена как (esc), переход в режим редактирования клавишами i или insert. Находясь в режиме команд, можно выполнять сложные операции редактирования текста с помощью клавиши "двоеточие"(:). При нажатии этой клавиши курсор устанавливается в последнюю строку экрана, поэтому данный режим называется режимом последней строки. Он считается особым типом режима команд.
Для того, чтобы открыть какой-то файл или создать новый надо выполнить команду:
# vi имя файла
Затем можно нажать клавишу i (или insert) и внести нужные изменения.
если вместо i нажать a, текст будет вставляться за символом на котором стоит курсор (обычно используется при редактировании файлов этот метод), если нажать o - будет вставлена новая строка.
Стирать текст следует выйдя из режима редактирования клавишей Escape и затем можно использовать клавишу x - она работает как клавиша del - стирает вперед, если нажимать shift+x, то будет стирать назад (по аналогии с backspace)
После редактирования нажмите (esc):wq чтобы выйти с сохранением текста

Основные команды перемещения по тексту

  • Перейти к строке с номером
(esc):номер или (esc),номер,shift+g
  • Поиск по тексту
(esc)/слово_которое_ищем
(esc) shift+j в конце строки объединит строки вместе.
(esc) shift+g - переместит в конец текста

Работа с буфером

(esc) dd - удалит строку в буфер
(esc) 10dd - удалит 10 строк в буфер
(esc) yy - скопирует строку в буфер
(esc) 10yy - скопирует 10 строк в буфер
(esc) p - вставит содержимое буфера под курсором
(esc) P - вставит содержимое буфера над курсором


Замена текста

(esc):s/что_меняем/на_что_меняем/g
g - обозначает замену до конца строки
если надо менять по всему файлу, то тогда пишем (esc):%s/что_меняем/на_что_меняем/g
появился символ % в начале команды


Как выйти из редактора vi

  • Выход осуществляется последовательностью нажатий
(esc):q
  • Выход без сохранения
(esc):q!
  • Выход с сохранением текста
(esc):wq или (esc):exit
  • Выход с принудительным сохранением (например, если файл read-only)
(esc):exit!

bash. Безопасность

Разница между командами "su" и "su -" [Занимательная и поучительная история]


Большенство пользуются и знают команду «su», но…
многие никогда и не знали про «su -»,
и некоторые набирают «su -» не зная почему, просто потому что им так посоветовал их знакомый гуру-линуксойд.


Предлагаю вашему вниманию наглядное(!!!) объяснение разницы.

Для начала теории


Согласно «man su»: Опции "-, -l, --login" означают "make the shell a login shell". Это означает, что при переходе с помощью «su -» запускается командная строка с настройками, как если бы логинились под указанного(либо по-умолчанию «root») пользователя «с нуля». В то время как просто «su» — запускает shell от указанного пользователя и при этом многие переменные окружения унаследываются от пользователя, который был до этого.


В подтверждение:
┌─[polzavatel]─────o Завёл переменную
└> export A=123
┌─[polzavatel]─────o Проверил
└> echo $A123
┌─[polzavatel]─────o Перехожу без "-"
└> suПароль: **пароль**
┌=[root]===========o Проверяю
└> echo $A123 # Переменная передалась
┌=[root]===========o Возвращаюсь обратно под "polzavatel"
└> exit
┌─[polzavatel]─────o Перехожу с "-"
└> su -
Пароль: **пароль**
┌=[root]===========o Проверяю
└> echo $A
                   # Пусто. Переменная не передалась.


Теперь для тех «кто всё равно не понял», либо «ну понятно, и чё дальше?!» — пример после которого одна русско говорящая гражданка страны на юге Канады сказала: "Ну я сегодня своих сисадминов хакну, а то они мне аську не ставят". А на следующий день: "Я их хакнула :)"

Пьеса «Гипотетическая история, которая может случится с каждым». Действующие лица (можете выбрать чья роль Вам ближе):
root — системный администратор,

polzavatel — обычный пользователь, без каких либо лишних прав в системе.
Действия происходят на каком-нибудь популярном дистрибутиве (проверено на многих, с некоторыми модификациями, но основной подход тот же).


Сцена первая — «Подготовка».
Компьютер, за ним сидит polzavatel и думает как же поставить себе аську\игрушку\кодеки\...(нужное подчеркнуть). Зная, что root пользуется командой «su» без "-" — у него появляется следующий коварный план(выполняется в консоли от имени polzavatel):

% PATH="/home/polzavatel:$PATH"
% echo "#!/bin/bash
chmod u+s /bin/vi
/bin/ping $*" > /home/polzavatel/ping% chmod +x /home/polzavatel/ping

Всё

Сцена вторая — «Социальная»
Компьютер, за ним сидит polzavatel, в ожидании мимо проходящего root. Тут появляется root, он мысленно чем-то занят, торопясь по своим делам.
polzavatel: "Уважаемый root, а у меня тут чего-то не работает — не могли бы вы помочь?.."
root: "Ну что ж...(с неохотой) давай-те посмотрим". Садится за компьютер и набирает в услужливо подставленной консоли:

% suПароль: **мегаСекретныйПароль** # Садясь за компьютер,
 с легкой параноидальностью прикрывая клавиатуру телом

root: "Ну что тут у вас не работает?"
polzavatel: "Знаете… почему то сеть не работает. 192.168.1.1 — не пингуется. А мне на него файлики закачать надо..."
root: "(Понятно)", набирая команду:

# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=4.71 ms...

polzavatel: "Ух-ты. Только ж не работало!.. Ну это прям «эффект присутствия» какой-то. Спасибо Вам дорогой root"
root облегченный, так быстро разрулившейся проблемой, уходит предусмотрительно отлогинившись.

Сцена третья — «Заключительная»
Компьютер, за ним сидит polzavatel — обстановка как в первой сцене. С довольной ухмылкой он выполняет в консоли от имени polzavatel следующие команды:

% /bin/vi /etc/shadow # Там он копируют хеш-пароля пользователя polzavatel на место хеш-пароля пользователя root. И сохранившись ":w!", выходит из редактора.
% su -
Пароль: **парольПользователя_polzavatel**
# whoami
root

!!!
ЗАНАВЕС


— — — — — — —
Пометки:
1) Вместо команды ping можно было бы использовать любую другую или несколько сразу. Соответственно поменяв при этом содержание просьбы polzavatel во второй сцене.
2) Вместо «chmod u+s /bin/vi» — опять же можно использовать и другую команду, которую хотелось бы выполнить root'овыми правами.

Ну кто искренне, держа руку на сердце — готов сказать что он не попался бы?!

P.S. Проверено на более полсотни сисадминах (разной степени продвинутости) — 100% попалось(причем все после объяснения разницы между «su» и «su -», и в ожидании подвоха), из них правда некоторые сказали: «А пинговать, то ведь можно было и не под root'ом...» (но уже после того как попались).

:)
Пример не только для того, чтобы бросались все бежать «хакать», а для того чтобы подумали, где бы Вас могли бы «хакнуть» и как этого избежать. Я знаю, а вы?

Язык bash часть 9

Язык командного интерпретатора bash. Part 8. «Обработка сигналов и протоколирование»

И настал, наконец, черёд восьмого топика о командном интерпретаторе bash. Им я завершаю свой цикл статей. Сегодня будет рассмотрена обработка сигналов в bash и протоколирование. Данный топик, также как и предущий, будет небольшим в связи с прямо пропорциональной зависимостью от объёма информации.
Возможности bash позволяют перехватывать и обрабатывать сигналы с помощью сценария. Под сигналами понимается средство, позволяющее сообщать процессам о различных событиях в операционной системе.
Список всех сигналов можно получить, введя команду:

$ kill -l

Перехватывать сигналы позволяет команда trap. Общий синтаксис команды:
trap [-lp] [команды сигнал сигнал …]

Ключ –l выводит список имён и номеров сигналов, а ключ –p выводит список команд, связанных с каждым сигналом. Сигналы следует указывать по именам либо по номерам.
Система всегда каким-либо образом реагирует на получение сигнала, то есть выполняет команду. Если же вместо команды указать пустую строку, то сигнал просто будет проигнорирован.
Приведу небольшой список наиболее часто встречающихся сигналов:
HUP – hangup, отбой;
INT – interrupt, прерывание;
QUIT – выход;
ILL – illegal instruction, программная ошибка;
FPE – floating point exception, вычислительная ошибка;
KILL – убить процесс;
TERM – termination, завершить процесс;
CHILD – завершился дочерний процесс.
Пример:

trap '' INT #игнорировать сигнал INT

Для того, чтобы протоколировать процесс работы своего скрипта, нужно использовать команду tee. Команда копирует данные из своего стандартного потока ввода и раздваивает их на стандартный поток ввода и в указанный файл лога. Для пояснения приведу пример:
$ cat listfile* | sort | tee check.file | uniq > result.file

Здесь, в файл check.file будут записаны данные из всех «listfile*», в отсортированном виде до того, как повторяющиеся строки будут удалены командой uniq.
Также существует другой способ протоколирования. Он заключается в использовании команды script, которая копирует в файл весь сеанс работы в текстовой консоли: ввод пользователя и вывод команд. Если производить запуск команды script вручную, то остановить протоколирование можно командой exit.
Приведу пример:

LOGFILE=logif [ "$LOGGING" == "true" ]; then
script myscript $LOGFILE; else
myscript;
fi

Для того, чтобы вызвать сценарий внутри своего сценария, нужно использовать команду exec:
exec script $0 $LOGFILE

===================Добвка из комментов=====================
Добавка:
1)Сигналы:
HUP – hangup(требуется переподключение, многие службы получив этот сигнал перечитывают свой конфиг);
INT – interrupt, прерывание с клавиатуры(что делать при нажатие Ctrl-C);
KILL – убить(безусловно — нет шанса отказатся умерать) процесс;
TERM – termination, завершить процесс — просьба процессу умереть;
STOP — застопить процесс (безусловно — нет шанса отказатся)
CONT — продолжить выполнение застопленного процеса

2) А еще есть: killall и xkill

3) У команды tee есть опция -a — означает append — то есть если указанный файл-логов существует то его не перезаписать. а дописывать в него

4) А про script — её часто просят запустить техподдержка в случае какой-нить проблемы и затем выполнить стандартный набор команд по списку, которые собирают информацию по системе — и затем прислать им собранный script'ом файл.

Язык bash часть 8

Язык командного интерпретатора bash. Part 7. «Функции»


Вот и наступил черёд седьмого топика цикла о языке командного интерпретатора bash. В некотором роде число «7» является везучим, как говорят в народе. Надеюсь, и меня не обойдёт данная примета.
Сегодня будут разобраны такие конструкции языка bash, как функции. Надеюсь, тебе не нужно рассказывать о том, что такое функция и для чего она применяется, ведь её смысл эквивалентен понятию функции из любого другого языка программирования. Объём информации сегодня не большой, поэтому пост имеет довольно скромные размеры. Итак, приступим к непосредственному разбору функций в bash.
Общий синтаксис оператора определения функции:

[function] имя_функции () {
список_комманд
}

Кроме K&R-стиля также применим BSD-стиль:

[function] имя_функции ()
{
список_комманд
}

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

#определение функции
func1 () {
  echo "Hello."
} #вызов функции
funс1

Функции принимают входные аргументы и возвращают код завершения. Доступ к входным аргументам осуществляется через позиционные параметры. Позиционный параметр 0 содержит имя функции. Внутри функции доступны локальные переменные сценария. Приведу пример:
param1=Hello
func2 () {
param2=${1-$param1}
echo "param2 = $param2"
}

Теперь пример с аргументами:
func3 () {
if [ "$1" ]
then
echo "Аргумент #1: \"$1\".-"
fi
if [ "$2" ]
then
echo "Аргумент #2: \"$2\".-"
fi
}
func3 #вызов функции без аргументов
func3 arg1 #вызов функции с одним аргументом
func3 arg1 arg2 #вызов функции с двумя аргументами

Если при выполнении функции произошла ошибка, происходит завершение выполнения функции с ненулевым кодом возврата. Код завершения можно задавать явно с помощью команды return. Код завершения в сценарии может быть получен через переменную $? и доступен до выполнения следующей команды.
Возможности bash позволяют переопределить stdin для функции, чтобы получать входные данные из файла. Для этого служит конструкция:

имя_функции ()
{
список_команд
} < файл
Также возмож
ен следующий вариант:
имя_функции ()
{
{
список_команд
} < файл
}
==========Добавка из коментов=====================
Пример1
Часто вижу линуксойдов, которые постоянно (когда хотят обратится к какому-то файлу) переходят в директорию(cd /home), затем смотрят её содержимое (ls), затем переходят дальше (cd /home/aonick), опять (ls) и тд… до достижения файла — для них:


lcd(){
  echo "Директория: $1"
  cd $1 && ls}
После этого переходить в нужную директорию можно так:
lcd /home
это команда и в директорию перейдет и сразу содержимое покажет.

Пример 2
Так как функция выполняется в той же сессии (в отличии от скрипта) — удобно например для команд настраивать автозаполнение по Тab-клавиши, напимер для команды rpm чтобы дописывал из списка установленных пакетов:

_rpm-refresh(){ complete -W "$(rpm -qa) -ivh -ql -qi" rpm; }

После этого — каждый раз когда запускаю функцию:
_rpm-refresh
обновляется список аргументов которые предлагаются по нажатию Tab.
И пользуясь командой rpm уже так, например:

rpm -ql apach<i><Нажимаю  дважды Tab></i>
и вижу список установленных пакетов начинающихся с «apach»

Дополнение:

Функция задается только в текущей сессии и после закрытия терминал про неё система забудет. Чтобы навеки-вечные задать своему пользователю функцию — её прописывают в файл ".bashrc" в домашней директории пользователя.

Язык bash часть 7

Язык командного интерпретатора bash. Part 6. «Условная подстановка параметров»


Продолжаю цикл статей о языке командного интерпретатора bash темой условной подстановки параметров. Благодаря условной подстановке параметров можно проверить, получил ли параметр значение, а также применять вместо его текущего значения другое.
Теперь перейдём к непосредственному разбору различных конструкций подстановок.

${параметр-строка}, ${параметр:-строка}


Логика конструкции: если параметр отсутствует, используется указанная строка, если непустое – значение по умолчанию.

Обе формы записи можно считать равнозначными в большинстве случаев. Символ ":" имеет значение когда параметр инициализирован, но имеет пустое значение. Приведу пару примеров для разъяснения ситуации:

param1=
echo ${param1-"Hello"}
Вывода не будет произведено, так как param1 инициализирован, но имеет пустое значение.

echo ${param2-"Hello"}
Будет выведена указанная строка, так как параметр не был инициализирован.

param2=
echo ${param2:-"Hello"}
Будет выведена указанная строка, так как параметр был инициализирован пустым значением, но использовалась конструкция ":-".

${параметр=строка}, ${параметр:=строка}


Логика конструкции: если параметр имеет пустое значение или не инициализирован, то ему присваивается указанное значение, после чего оно подставляется. Символ ":" имеет значение когда параметр инициализирован. Разберём на примерах:

param3=
echo ${param3="Hello"}
Так как параметр не инициализирован, он не будет выведен.
echo ${param4:="Hello"}
Будет выведена указанная строка, так как param4 не инициализирован.
param5="param"
echo ${param:="Hello"}
Будет выведено первоначальное значение параметра.

${параметр+строка}, ${параметр:+строка }


Логика конструкции: если параметр имеет значение, то используется оно, в противном случае – альтернативная строка. Различия конструкций разберём на примерах:

echo ${param6+"Hello"}
Ничего не выводится.

param7=
echo ${param6+"Hello"}
Будет выведена указанная строка.
param8=123
echo ${param8+"Hello"}
Будет выведена указанная строка.

echo ${param9:+"Hello"}
Ничего не выводится.

param10=
echo ${param10:+"Hello"}
Ничего не выводится.

param11=123
echo ${param11:+"Hello"}
Будет выведена указанная строка.

${параметр? сообщение}, ${параметр:? сообщение}

Логика конструкции: если параметр инициализирован, используется его значение; если параметр не инициализирован – выводится сообщение.

echo ${param12?"hello"}
Выводится сообщение.

echo ${param12:?"hello"}
Выводится сообщение.
param13=
echo ${param13?"hello"}
Не выводится ничего (выводится пустое значение).

param14=123
echo ${param14:?"hello"}
Выводится значение параметра.

${#параметр}

Логика конструкции: возвращается длина значения параметра в байтах. В случае массивов, команда ${#array} возвращает длину первого элемента массива.

Исключения:
1) ${#*} и ${#@} возвращает количество аргументов (позиционных параметров).
2) Для массивов, ${#array[*]} и ${#array[@]} возвращает количество элементов в массиве.

param15=123
echo ${#param15}
Будет выведена длина значения параметра (в данном случае 3).

${параметр#шаблон}, ${параметр##шаблон}


Логика конструкции: удаляет из параметра наименьшую (наибольшую) подстроку, удовлетворяющую указанному шаблону, начиная из головной части значения параметра.

Пример:

param16=12345
echo ${param16#123}
Будет выведено 45.
$ echo $PWD/home/istergul/fold
$ echo ${PWD##*/}
fold


${var%Pattern}, ${var%%Pattern}

Логика конструкции: удаляет из параметра наименьшую (наибольшую) подстроку, удовлетворяющую указанному шаблону, начиная из хвостовой части значения параметра. По сути данная конструкция повторяет предыдущую, только начиная с конца значения параметра. 


=========================Добавление из комментов================
Пример 1
Часто мои скрипты начинаются с такой строчки:


Dir=${1-.}
То есть скрипт запускается и в качестве параметра ему указывается директория, которую надо обработать. Если директория не указана, то обрабатывается текущая директория.

Пример 2
Для начала задам переменную

Pic=/usr/share/wallpapers/Wolf.jpg
Вывод без первых трех символов(любых)
echo ${Pic#???}
r/share/wallpapers/Wolf.jpg


Пример 3
Для той же переменной

Pic=/usr/share/wallpapers/Wolf.jpg
Вывод с пятого по 9ый символы (то есть пропустить от начала 4ре символа и напечатать следующие 5)
echo ${Pic:4:5}
/shar


Пример 4
Переименование всех jpg-файлов в текущей папке под общий шаблон: Image_число.jpg
N=10000; for i in *.jpg;do let N=N+1; mv -i "$i" Image_${N:1}.jpg;done
Работает для не более 9999 файлов в текущей директории

Пример 5
Pic=/usr/share/wallpapers/Wolf.jpg
Перейти в папку содержащую эту картинку
cd ${Pic%/*}
это соответствует
cd /usr/share/wallpapers


Пример 6
Если файл картинка(jpg), то просмотеть ей (например, при помощи програмки eog)

[ "${Pic##*.}" = jpg ] && eog $Pic
 

Язык bash часть 6

Язык командного интерпретатора bash. Part 5. «Операторы цикла»


И вот настал черёд пятого топика цикла. В нём я продолжу рассматривать управляющие структуры командного интерпретатора bash. В предыдущем посте были разобраны условные операторы. Теперь настал черёд таких неотъемлемых языковых структур, как операторы цикла. Циклы, как и условия, являются теми инструментальными средствами, которые обеспечивают управление порядком исполнения команд.
Bash поддерживает циклы типа for, while, until и select.
Теперь перейдём к подробному рассмотрению каждого из них.

Оператор цикла for

Общий синтаксис оператора for:
for переменная [in шаблон]
do
список команд
done

Цикл for в bash значительно отличается от цикла for в таких языках программирования, как C или PHP. Поэтому если вы программируете на C, вам нужно будет привыкнуть к этим отличиям, чтобы не путаться.
В результате подстановки шаблона получается список слов. При каждой итерации переменная принимает каждое последующее значение этого списка, и выполняются команды, стоящие между do и done. Итерации прекращаются по исчерпании слов в списке.

$ for day in Mon Tue Wed Thu Fri
do
echo “Сегодня $day
done

Зарезервированные слова оператора for также можно писать в одну строчку, как это было в предыдущем посте для оператора if. Для этого нужно ставить ";". Перепишем предыдущий пример с учётом данной возможности:
$ for day in Mon Tue Wed Thu Fri; do echo “Сегодня $day”; done

Отсутствие конструкции [in шаблон] эквивалентно записи in $@. О параметре $@ говорилось в моей первой статье.

Оператор цикла while

Общий синтаксис оператора while:


while список1
do
список2
done

Сперва выполняется список1. Если он завершается успешно, т. е. возвращает нулевой код, управление переходит списку2. Итерации продолжаются до тех пор, пока результат выполнения списка1 не станет ненулевым. Например:
i=10
while [ $i gt 0 ]; do
echo $i
i=$(($i-1))
done; echo 'end'


Оператор цикла until

Общий синтаксис оператора until:


until список1
do
список2
done

Сперва выполняется список1. Если он завершается неуспешно, то есть с ненулевым кодом возврата, управление переходит списку2. Итерации продолжаются до тех пор, пока результат выполнения списка1 не станет нулевым. Например:
i=10
until [ $i lt 0 ]; do
echo $i
i=$(($i-1))
done; echo 'end'


Оператор цикла select

Общий синтаксис оператора select:


select переменная [in шаблон]
do
список
done

В результате подстановки шаблона получается список слов. К этим словам оператор добавляет порядковые номера и выводит весь набор в стандартный поток ошибок. Отсутствие конструкции [in шаблон] эквивалентно записи in $@. После этого выводится приглашение и считывается строка из стандартного потока ввода. Если строка содержит номер, соответствующий какому-либо слову из списка, то переменная получает его в качестве значения. Если подходящего слова не было найдено, то значением переменной становится пустая строка. После этого выполняется список команд, и итерации продолжаются до тех пор, пока в строке ввода не попадётся символ конца файла или пока в списке команд не встретится break или return.
Команды break и return служат для управления ходом выполнения цикла. Команда break прерывает исполнение цикла, в то время как return возвращает код результата (нулевой или ненулевой).
Оператор select полезен для создания нумерованных меню. Например, в каталоге ~/temp находится 3 файла: proto.txt, file.txt и readme. Пример фрагмента скрипта, позволяющего быстро просмотреть любой из них.

echo "Выберите файл для просмотра:"
select file in ~/temp/* Quit;
do
if [ -f $file ]; then cat $file;
else break;
fi
done

Запустив данный скрипт, мы увидим на экране:
Выберите файл для просмотра:
1) /home/istergul/temp/file.txt
2) /home/istergul/temp/proto.txt
3) /home/istergul/temp/readme
4) Quit
=================Добавка из комментов===========================
Пример for — 1ый(простой):
#Создает html-галерейку из jpg-картинок в текущей папке


for i in *.jpg; do
        echo "<IMG src=$i><HR>"
done > gallery.html


Пример for — 2ой(тоже простой, но из моего bash_history):
#Выкачевает рейтинг на сегодня с одного сайта

for i in {1..22};do  
        wget -nv http://open-life.org/people/good/page$i -O -|zcat
done > reiting_$(date +%y%m%d).html


Пример while — 1ый(бесконечный цикл):
#Сидюк-хронометр

while : ; do 
        eject; sleep 2; eject -2
done 


Пример while — 2ой(использование в построчной обработке файла)
#Подсчитать сумарный размер jpg-файлов в текущей папке

ls -l *.jpg| (  
        while read Perm nL Uid Gid Size others;do
                let SumSize=SumSize+$Size;
        done;
        echo $SumSize )
 
===============Reply==================
#Подсчитать сумарный размер jpg-файлов в текущей папке

Пример интересный, но всё же лучше для этих целей использовать:

du -bc *.jpg | tail -n1 

Язык bash часть 5

Язык командного интерпретатора bash. Part 4. «Условные операторы»

Данный топик является четвертым топиком цикла «Язык командного интерпретатора bash». Он будет повествовать о таких управляющих структурах языка, как условные операторы. Но перед тем, как перейти к их описанию, необходимо остановиться на некоторых нюансах, которые сделают рассмотрение нижеизложенного материала более понятным.
Во-первых, разберём, что такое список команд. Список команд – это одиночная команда, конвейер или последовательность команд/конвейеров, разделённых одним из следующих операторов: ";", "&&", "||", завершённая точкой с запятой.
; — оператор последовательного выполнения нескольких команд. Каждая последующая команда начинает выполняться только после завершения предыдущей (неважно, успешного или нет);
&& — оператор выполнения команды только после успешного выполнения предыдущей;
|| — оператор выполнения команды только после ошибочного выполнения предыдущей.
Кодом успешного завершения является 0, а ошибочного — не ноль (зависит от типа ошибки). Не нужно путать с обычными языками программирования, когда 1 является аналогом true, а 0 – false.
Теперь можно приступить к непосредственному рассмотрению условных операторов.

Оператор вариантов case


Общий синтаксис оператора case:

case значение in
шаблон1) список1;;
шаблон2 | шаблон3) список2;;
esac

Логическая последовательность выполнения оператора case:
а) ищется первый шаблон, совпадающий со значением;
б) если он найден, выполняется соответствующий ему список команд, завершённый ";;";
в) управление передаётся операторам, следующим за конструкцией case.
Шаблон и список разделяются символом ")". Одному списку команд может соответствовать несколько условий, тогда их нужно разделять символом "|".
В шаблонах можно использовать символы "*", "?", "[ ]", о которых было рассказано во втором топике цикла. С их помощью можно реализовать инструкцию, действующую как default в операторе switch таких языков, как C, PHP.
Приведу пример использования case
:
echo -n "[Универсальный просмоторщик] Укажите имя файла: "; read File
case "$File" in
*.jpg|*.gif|*.png)
eog $File;;
*.pdf)       evince $File   ;;
*.txt)       less $File   ;;
*.html)      firefox $File   ;;
/dev/*)      echo "Ну это страшные файлы."   ;;
*)
echo "Ну ладно, ладно - не такой уж и универсальный."
echo "Этот тип файлов мне не знаком. Не знаю, чем его просмотреть."
;;
esac

Ещё один пример использования конструкции case:
echo "Ошибка. Кому отправить сообщение?"
echo "Начальнику: b"
echo "Коллегам: c"
echo "Никому: any key"
read answercase $answer in
   b|B) mail s "error log" boss < error.log;;
   c|C) mail s "Help! error log" c denis nick < error.log;;
   *) echo "error"; exit;;
esac


Условный оператор if

Общий синтаксис оператора if:

if список1 then
список2
[elif список3 then
список4]
[else
список5]
fi

Квадратные скобки здесь указывают на необязательные конструкции. Логическая последовательность выполнения оператора case:
а) выполняется список1;
б) если он выполнен без ошибок, выполняется список2. В противном случае выполняется список3, и если он завершается без ошибок – список4. Если же и список3 возвращает код ошибки, выполняется список5;
в) управление передаётся операторам, следующим за конструкцией if.
Приведу пример использования if:

if grep -q Bash filethen echo "Файл содержит, как минимум, одно слово Bash."
fi

Когда if и then располагаются в одной строке, то конструкции if и then должны завершаться точкой с запятой. Например:
$ if [ $? ne 0 ]; then echo Error”; fi

Теперь, зная о возможни располагать if и then в одной строке, перепишем вышеуказанный пример:
if grep -q Bash file; then 
echo «Файл содержит слово Bash
fi


Оператор test и условные выражения

В вышеприведённом примере вместо анализа кода завершения использована проверка условия. Две формы такой проверки эквивалентны: встроенная команда test и [условие]. Например, для проверки существования файла нужно написать:

test e <файл>

или

[ -e <файл> ]

Если используются квадратные скобки, они обязательно должны быть отделены друг от друга пробелом, потому что "[" – это название команды, а "]" – это обязательный последний аргумент её завершения.
В случае успешной проверки условия, возвращается 0, а в случае ложности – код ошибки 1.
Команда test может проверять строку на пустоту. Непустая строка приводит к коду завершения 0. Пуста, соответственно – 1. Например:

$ test $USER; echo $?
0

Конструкция "[[ ]]" более универсальна, по сравнению с "[ ]". Этот расширенный вариант команды test. Внутри этой конструкции не производится никакой дополнительной интерпретации имен файлов и не производится разбиение аргументов на отдельные слова, но допускается подстановка параметров и команд. Например:
file=/etc/passwdif [[ -e $file ]]
then
   echo “Файл паролей найден.”
fi

Конструкция "[[ ]]" более предпочтительна, нежели "[ ]", поскольку поможет избежать некоторых логических ошибок. Например, операторы "&&", "||", "<" и ">" внутри "[[ ]]" вполне допустимы, в то время как внутри "[ ]" порождают сообщения об ошибках.
Конструкция "(( ))" позволяет производить вычисление арифметических выражений внутри неё. Если результатом вычислений является ноль, то возвращается код ошибки. Ненулевой результат вычислений даёт код возврата 0. То есть полная противоположность инструкциям test и "[ ]", обсуждавшимся выше.
Оператор if позволяет допускать наличие вложенных проверок:

if echo "Следующий *if* находится внутри первого *if*."
   if [[ $comparison = "integer" ]]
   then (( a < b ))
   else
      [[ $a < $b ]]
   fi
then
   echo '$a меньше $b'
fi


Условные выражения можно комбинировать с помощью обычных логических операций:
! <выражение> – отрицание;
<выражение1> –a <выражение2> – логическое И;
<выражение1> –o <выражение2> – логическое ИЛИ.

Элементарные условные выражения для файлов:

-e — файл существует;
-f — обычный файл (не каталог и не файл устройства);
-s — ненулевой размер файла;
-d — файл является каталогом;
-b — файл является блочным устройством (floppy, cdrom и т.п.);
-c — файл является символьным устройством (клавиатура, модем, звуковая карта и т.п.);
-p — файл является каналом;
-h — файл является символической ссылкой;
-L — файл является символической ссылкой;
-S — файл является сокетом;
-t — файл связан с терминальным устройством;
-r — файл доступен для чтения (пользователю, запустившему сценарий);
-w — файл доступен для записи (пользователю, запустившему сценарий);
-x — файл доступен для исполнения (пользователю, запустившему сценарий);
-g — (sgid) флаг для файла или каталога установлен;
-u — (suid) флаг для файла установлен;
-k — флаг sticky bit установлен;
-O — вы являетесь владельцем файла;
-G — вы принадлежите к той же группе, что и файл;
-N — файл был модифицирован с момента последнего чтения;
файл1 -nt файл2 – файл1 более новый, чем файл2;
файл1 -ot файл2 – файл1 более старый, чем файл2;
файл1 -ef файл2 – файл1 и файл2 являются «жесткими» ссылками на один и тот же файл.

Элементарные условные выражение для сравнения строк:

-z строка – длина строки равна 0;
-n строка – длина строки не равно 0;
строка1 == строка2 – строки совпадают (аналог “=”);
строка1 !== строка2 – строки не совпадают (аналог “!=”);
строка1 < строка2 – строка1 предшествует строке2 в лексикографическом порядке;
строка1 > строка2 – строка1 следует за строкой2 в лексикографическом порядке.
Арифметическое условное выражение имеет формат:
аргумент1 операция аргумент2, где аргументами являются целые числа, и допустимы следующие операции:
-eq – равно;
-ne – не равно;
-lt – меньше;
-le – меньше или равно;
-gt – больше;
-ge – больше или равно;
< — меньше (внутри двойных круглых скобок);
<= — меньше или равно (внутри двойных круглых скобок);
> — больше (внутри двойных круглых скобок);
>= — больше или равно (внутри двойных круглых скобок).

Перепишем предыдущий пример с использованием оператора if:
echo "Ошибка. Кому отправить сообщение?"
echo "Начальнику: b"
echo "Коллегам: c"
echo "Никому: any key"
read answerif [ "$answer" == "b" o "$answer" == "B" ]; then
   mail s "error log" boss < error.log;
elif [ "$answer" == "c" o "$answer" == "C" ]; then
   mail s "Help! error log" c denis nick < error.log;
else
echo "error"; exit;
fi

Язык bash часть 4 (ssmtp)

Резервное копирование домашней папки на getdropbox.com, плюс отсылка логов об этом себе на почту через gmail.com


Цель данной работы — создать архив домашней папки пользователя, положить данный архив в какую-либо локальную папку, скопировать архив в папку dropbox, послать на нужную почту отчет об этом факте, воспользовавшись для этого SMTP-сервером gmail.com.

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


0. Заводим себе аккаунт на getdropbox.com. Кстати — если уж будете регистрироваться, пожалуста, вспользуйтесь моей ссылкой:
getdropbox.com. Вам в этом случае сразу отпилят в виде бонуса +250 Мб (при регистрации «напрямую» этого не будет), и мне собственно — тоже, те же самые 250 Мб. Мелочь, а приятно — мегабайты лишними быть не могут.

1. Ставим ssmtp, при помощи которого будем отсылать почту:


root@sysadm-desktop:~# apt-get install ssmtp -y


2. Идем на gmail.com и заводим там себе аккаунт. У нас будет robot@gmail.com.
3. Идем в свою домашнюю папку, и смотрим, что нам нужно бэкапить, а что нет. В соответствии с этим составляем команду для архиватора. У меня вышло вот что:


tar czvf /tmp/sysadm.tar.gz /home/sysadm/.* /home/sysadm/* --exclude=.gvfs --exclude=В\ плеер --exclude=Видео --exclude=Nexuiz --exclude=VBox --exclude=video --exclude=. --exclude=.. --exclude=/home/sysadm/.thumbnails/

Я наисключал некоторые каталоги, которые слишком объемные, и данные из них в резервном копировании не нуждаются.

Запускаем, смотрим как оно отработало.


4. Настраиваем ssmtp.

root@sysadm-desktop:~# cat /etc/ssmtp/ssmtp.conf 
root=robot@gmail.com
mailhub=smtp.gmail.com:587
hostname=smtp.gmail.com:587
UseSTARTTLS=YESAuthUser=robot@gmail.comAuthPass=yarobotFromLineOverride=YES

root@sysadm-desktop:~# cat /etc/ssmtp/revaliases 
root:robot@gmail.com:smtp.gmail.com:587
sysadm:robot@gmail.com:smtp.gmail.com:587


В файле /etc/ssmtp/revaliases я описал двоих пользователей — от root будем выполнять собственно всю работу через crontab, а для sysadm — для проверки, ну и просто — пусть будет.

5. Проверяем, как все фурычит:


root@sysadm-desktop:~# echo "Test" | ssmtp sysadm@gmail.com


Идем в почтовый ящик sysadm@gmail.com, и в папке «Спам» находим свое письмо. Если находим — то все отлично работает! Что бы такие письма не попадали в спам, нужно создать фильтр, и применять на письма от robot@gmail.com какой-нибудь ярлык.

6. Пишем скрипт для всего того, что мы обозначили в самом начале.


root@sysadm-desktop:~# cat /etc/cron.daily/arc_sysadm 
#!/bin/bash

home_dir=/home/sysadm
tmp_dir=/home/sysadm/files
arc_dir=/home/sysadm/Dropbox/backups
arc_name=sysadm_backup.tar.gz
log=/root/log_arc.log
log_tar=/root/log_tar.log
log_tar_error=/root/log_tar_error.log
log_mail=/root/log_mail.log
# --------------------------------------------------------

echo_log ()
{
echo $(date '+%d-%m-%y %H:%M:%S') $1
echo $(date '+%d-%m-%y %H:%M:%S') $1 >> $log}
# --------------------------------------------------------

echo > $log
echo > $log_tar
echo > $log_mail
echo > $log_tar_error

echo_log "Резервное копирование начинается"


echo_log "home_dir="$home_dir
echo_log "tmp_dir="$tmp_dir
echo_log "arc_dir="$arc_dir
echo_log "arc_name="$arc_name
echo_log "log="$log
echo_log "log_tar="$log_tar
echo_log "log_tar_error="$log_tar_error
echo_log "log_mail="$log_mail

tar czvf $tmp_dir/$arc_name $home_dir/.* $home_dir/* --exclude=.gvfs --exclude=В\ плеер --exclude=Видео --exclude=Nexuiz --exclude=VBox --exclude=video --exclude=. --exclude=.. --exclude=/home/sysadm/.thumbnails/ 1>> $log_tar 2>> $log_tar_error

echo_log "Резервное копирование закончено"

echo "Subject: Резервное копирование домашней папки sysadm" >> $log_mail
echo >> $log_mail
cat $log >> $log_mail
echo >> $log_mail

echo === Error-лог tar-а: ================================ >> $log_mail
echo >> $log_mail
cat $log_tar_error >> $log_mail
echo >> $log_mail

echo === Лог tar-а: ===================================== >> $log_mail
cat $log_tar >> $log_mail

cat $log_mail | ssmtp sysadm@gmail.com

rm -f $arc_dir/$arc_name
cp $tmp_dir/$arc_name $arc_dir/$arc_name


Поправить здесь нужно все переменные из самого начала под свою файловую структуру, и — вписать свою строку для архиватора, которую мы составили в п.3. Вроде больше ничего трогать не надо.

Не забываем сделать:


root@sysadm-desktop:~# chmod +x /etc/cron.daily/arc_sysadm 


Наш скрипт будет выполняться раз в сутки.

Имеем: раз в сутки производится выборочное архивирование домашней папки в два места: в локальный каталог и на сетевой ресурс dropbox, а отчет об этом факте падает на нужную почту.