Оператор test и условные выражения. Потоки, программные каналы и перенаправления

Сегодня начнём разбирать возможности bash. Так как этот вопрос довольно объёмный, то его придётся разбить на несколько частей. Так что пойдём от простого к сложному. Кстати, есть очень большая вероятность, что информация, усвоенная при изучении bash, пригодится при работе с другими командными интерпретаторами.
Стандартный поток ввода и вывода.
Это довольно важные понятия означают всего навсего то, откуда по умолчанию читает программа данные (stdin) и куда выводит результаты своей работы (stdout). Также существует стандартный поток вывода ошибок (stderr). Обычно это экран (точнее, терминал пользователя) + клавиатура. Для чего это надо знать? А дело в том, что все эти потоки можно перенаправлять. Чаще всего для ввода/вывода используют файлы.
Например, так можно создать файл, содержащий список фалов в указанной директории.
$ ls -l > ~/file_with_files
Кстати, стоит помнить, что при следующем выполнении, файл будет полностью переписан, и всё, что было раньше потеряется. Если же нужно дописать в конец файла, то нужно использовать «>>» вместо «>»
$ ls -l >> ~/file_with_files
Также, при выполнении команды можно разделять потоки.
stdin имеет номер 0
stdout имеет номер 1
stderr имеет номер 2
То есть можно выводить ошибки в отдельный файл, причём обычные сообщения будут при этом отображаться как обычно. Для этого нужно перед «>» поставить число 2 (номер потока, аналогично для stdin, stdout). Например так
$ find / -name .bashrc 2> ~/finderrors.txt
Кроме того, существует такое устройство как /dev/null, на который можно также перенаправлять вывод. При этом ничего из направленного не будет нигде отображаться.
$ find / -name asdf 2 > /dev/null
Вывод можно направлять и в другую команду. Например, следующая команда выведет количество слов в файле
$ cat ~/finderrors.txt > wc -w
Если вам нужно написать скрипт, в котором какая-то программа требует ввода, то можно направить в неё содержимое файла
$ wc -w < ~/finderrors.txt
Примечание. «>» без указания номера потока трактуется как «1 >». То есть выводится будет только stdin.
Конвейеры.
Наверняка вы видели команды следующего вида:
$ cat /etc/bash.bashrc | more
В результате её работы будет приостановлен вывод при заполнении экрана. Так вот, «|» и есть этот самый конвейер. Говоря по-умному, это - канал, в который один процесс может только писать, а другой - только читать. Выборка и помещение в такой конвейер идёт по принципу FIFO (First In - First Out). Также этот принцип называется очередь, что очень просто и точно характеризует его работу. Конвейеры используются для того, чтобы скомбинировать работу нескольких маленьких программ.
Разберём работу следующей команды.
$ cat myfile | grep Linux | we -1
Сначала cat myfile выводит содержимое файла myfile, затем grep Linux считывает вывод и выделяет только строки содержащие слово Linux. Потом wc -l считает количество строк. В результате мы получим количество строк, содержащих слово Linux.
Очень удобно использовать утилиту xargs вместе с «|». xargs читает элементы вывода stdin, разделённые пробелами и выполняет программу, передав их ей один или несколько раз.
Например
$ find /tmp -name core -type f -print | xargs /bin/rm -f
Эта команда находит файлы с именем core в директории /tmp и удаляет их.
Специальные символы.
В отличие от ОС Windows, имена файлов в Linux могут содержать почти любые символы (например имя файла example*of:file вполне реально). Но некоторые знаки bash использует как служебные. И для корректной работы необходимо эти символы экранировать. Это можно делать несколькими способами.
Можно брать выражение в кавычки. Например
$ cp «example*of:file» ~
Также можно использовать одиночные кавычки
$ cp "example*of:file" ~
Отличие состоит в том, что в одиночных кавычек теряют своё значение все спецсимволы, в двойных - все, кроме $ и \
Но самым универсальным является С-подобный способ отмены специальных символов. Для этого достаточно перед символом поставить «\» (без кавычек). Например наша команда будет выглядеть следующим образом.
$ cp example\*of\:file ~
Выполнение команд.
Существует несколько символов для организации выполнения команд.
Если нужно последовательно выполнить несколько команд, то их следует разделить символом «;». Например, следующая последовательность скомпилирует файл (а компиляция - долгий процесс, можно в это время поспать!), затем выключит компьютер.
$ make ; sudo shutdown -h now
Если же нужно выполнить программу в фоновом режиме (то есть вернуть управление пользователю сразу после запуска, это бывает удобно при запуске графических приложений), то необходимо после команды поставить символ «&». Например
$ sudo synaptic &
В результате у нас запустится synaptic и можно будет не выходя из него, пользоваться текущим эмулятором терминала.
А что же делать, если нам нужно выполнить команду только в том случае, если операция успешно завершится. Например, есть следующая задача:
Нужно скомпилировать файл. Для этого нужно выполнить configure, make, sudo make install. Причём выполнять нужно только в том случае, если предыдущая команда закончилась успешно.
В таких случаях применяет последовательность «&&». Оператор, стоящий после «&&» выполняется только в том случае, если предыдущая завершилась успешно. То есть у нас это будет выглядеть так:
$ ./configure && make && sudo make install
Если же нужно выполнить только в том случае, если программа завершится с ошибкой, то нужно использовать «||». Например, усложним задачу. Нужно будет при ошибке записать её в файл, а затем, независимо от окончания, выключить компьютер.
$ ./configure && make && make install || echo fail > ~/errorfile ; sudo shutdown -h now
Шаблоны имён файлов
Проще всего их перечислить в табличке. Стоит помнить, что шаблоны можно комбинировать в одной команде.
Шаблон Значение
* Любая последовательность символов, в том числе и пустая
? Любой одиночный символ
{a,b,c,d} Любой из символов, перечисленных в скобках
Любой символ из указанных интервалов
[^0-6] Любой символ, не входящий в указанные интервалы
Проще всего их разбирать на примере.
Допустим, у нас есть папка, содержащая следующие файлы.
Glava01, Glava02, Glava03, Glava04, Glava05, Glava15, Glava17.
Применим шаблон Glava0* и получим список Glava01, Glava02, Glava03, Glava04, Glava05.
Применим шаблон Glava?5 и получим список Glava05, Glava15.
Применим шаблон Glava?{4,5} и получим список Glava04, Glava05, Glava15.
Применим шаблон Glava0 и получим список Glava01, Glava02, Glava03.
Выполнение арифметических выражений.
Да, bash и такое умеет. Для этого есть две формы
первая $[выражение]
вторая $((выражение))
Например
$ echo $
В результате выполнения выведется число 6. Если выражение некорректно, то bash выдаст сообщение об ошибке.
Подстановка команд.
Подстановка команд является очень мощным средством bash. Смысл в том, что записанная команда меняется на результат её выполнения. Существует две формы записи
$(команда) и `команда` (в этом случае используются не одиночные кавычки, а символы, получающиеся при комбинации SHIFT+~). Например, вот яркий пример, который используется в Debian при установке заголовочных пакетов текущего ядра.
# apt-get install linux-headers-`uname -r`
Команда uname -r при своём выполнении выдаёт версию используемого ядра. То есть при выполнении у меня она меняется на
# apt-get install linux-headers-2.6.25-2-686
Причём, у вас она может приобрести другой вид. Также можно поменять ядро, а пакеты устанавливать той же командой.
Фильтры
Это команды, которые могут преобразовать входной поток данных и вывести результат на стандартный поток вывода.
Команда Краткое описание
cat На стандартный вывод (то есть
на экран) выводится содержимое указанного файла (или нескольких фай-
лов, если их имена последовательно задать в качестве аргументов команды).
grep, fgrep, egrep Ищут во входном файле или данных со стандартного ввода строки, содержащие указанный шаблон, и выдают их на стандартный вывод
tr Заменяет во входном потоке все встречающиеся символы, перечисленные в заданном перечне, на соответствующие символы из второго заданного перечня
comm Сравнивает два файла по строкам и выдает на стандартный вывод 3 колонки: в первой - строки, которые встречаются только в 1-ом файле, во второй - строки, которые встречаются только во 2-ом файле, и в третьей - строки, имеющиеся в обоих файлах
pr Форматирует для печати текстовый файл или содержимое стандартного ввода
sed Строковый редактор, использующийся для выполнения некоторых преобразований над входным потоком данных (берется из файла или со стандартного ввода)
more и less Выводят содержимое файла на экран отдельными страницами размером как раз в целый экран.
wc Подсчитывает количество слов, строк или байт в потоке.
Например,
$ grep CONFIG_XEN . -Rl | xargs -i sed -i -e "s/CONFIG_XEN/CONFIG_LUPO/g" {}
Ищет файлы в текущей папке, содержащие строку «CONFIG_XEN» и меняет её на «CONFIG_LUPO» во всех найденных файлах.
Вот тут мы и сделаем перерыв для того, чтобы разобраться во всём объёме материала. Bash - очень мощный интерпретатор и для его освоения нужна практика. В следующей статье будет рассматриваться создание скриптов для него. Начнём программировать. До следующих встреч!
Метки: линух, статьи

Tags: Зачем нужен конвейер команд в bash

Когда ты работаешь в команде, вы подпитываете друг друга эмоциями, своей работой, успехами и достижениями....

Команды /scoreboard teams add название /scoreboard teams list /scoreboard teams join название /scoreboard teams leave ...

google.com/bin/echo foo | grep bar" .... getpid() = 13726 <– PID ..... 1 · Почему в Ubuntu 16.04 медленный apt-get dist-upgrade? ... Спасибо, очень интересная статься… но как всегда нужна мера, чтобы не полочалось такого:

Feb 25, 2009 - do команды done. Рассмотрим небольшой пример: #!/bin/bash .... Конвеер - очень мощный инструмент для работы с консолью Bash. .... to do some stuff и пытаться понять почему каталог programs to do не найден… ... Может быть для этого нужны какие-то настройки, но у меня при этом...

Подскажите с решением нескольких заданий, пожалуйста. #!/bin/bash | Автор топика: Илья

30. Создайте конвейер для получения списка только имен и прав доступа к файлам, которые в данный момент находятся в Вашем рабочем каталоге. 31. Измените построенный конвейер так, чтобы список сохранялся в файле spisok Вашего HOME-каталога, а на экран выводилось только число файлов в списке. 32. Выведите на экран содержимое файла /etc/passwd, упорядоченное по полю с именем пользователя. 33. Создайте псевдоним loggedon, который будет выводить на экран упорядоченный в алфавитном порядке список имен работающих в системе пользователей. 34. Присвойте переменной IAM Ваше имя регистрации. Запустите еще один shell. Видите ли Вы эту переменную? Что нужно сделать, чтобы увидеть ее в порожденном shell? Измените значение переменной IAM в порожденном shell. Выйдите из порожденного shell. Посмотрите значение этой переменной в исходном shell. Объясните результат. 40. Напишите shell-программу hello, обеспечивающую следующую реакцию на аргументы командной строки: - аргумент “-d” - программа будет выполнять команду date; - аргумент “-l” - программа выведет содержимое текущего каталога; при отсутствии аргументов или неправильных аргументах в командной строке программа будет выводить справку о своих опциях. 41. Напишите программу words, которая будет выдавать пользователю приглашение на ввод по одному слову до тех пор, пока он не введет слово “end”. Запомните все введенные слова. После ввода слова “end” выведите на экран все введенные слова. Спасибо, если хотя бы одно из этого подскажете

Виталий  32. cat /etc/passwd | sort

Advanced Bash-Scripting Guide - Linux по-русски

Зачем необходимо знание языка Shell? 2. ..... Передача вывода от команды echo команде read, по конвейеру; 33-1. сценарий-обертка; 33-2. Более...

Перенаправление ввода/вывода - OpenNet

Advanced Bash-Scripting Guide: Искусство программирования на языке... Однострочные команды перенаправления # (затрагивают только ту строку, ... В конвейер передается только stderr. exec 3>&1 # Сохранить текущее...

Данный топик является четвертым топиком цикла «Язык командного интерпретатора 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 answer case $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

fi

Квадратные скобки здесь указывают на необязательные конструкции. Логическая последовательность выполнения оператора case:
а) выполняется список1;
б) если он выполнен без ошибок, выполняется список2. В противном случае выполняется список3, и если он завершается без ошибок – список4. Если же и список3 возвращает код ошибки, выполняется список5;
в) управление передаётся операторам, следующим за конструкцией if.
Приведу пример использования if:
if grep -q Bash file then 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/passwd if [[ -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 answer if [ "$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. А именно, будут рассмотрены операторы циклов. А сейчас жду комментариев и критики:).

UPD : Спасибо пользователю

Оператор for-in предназначен для поочередного обращения к значениям перечисленным в списке. Каждое значение поочередно в списке присваивается переменной. Синтаксис следующий:

for переменная in список_значений do команды done

Рассмотрим небольшой пример:

#!/bin/bash for i in 0 1 2 3 4 #переменной $i будем поочередно присваивать значения от 0 до 4 включительно do echo "Console number is $i " >> / dev/ pts/ $i #Пишем в файл /dev/pts/$i(файл виртуального терминала) строку "Console number is $i" done #цикл окончен exit 0

После выполнения примера в первых 5 виртуальных консолях (терминалах) появится строка с её номером. В переменную $i поочередно подставляются значения из списка и в цикле идет работа со значением этой переменной.

Циклы. Цикл while

Цикл while сложнее цикла for-in и используется для повторения команд, пока какое-то выражение истинно(код возврата = 0). Синтаксис оператора следующий:

while выражение или команда возвращающая код возврата do команды done

Пример работы цикла рассмотрим на следующем примере:

#!/bin/bash again =yes #присваиваем значение "yes" переменной again while [ "$again " = "yes" ] #Будем выполнять цикл, пока $again будет равно "yes" do echo "Please enter a name:" read name echo "The name you entered is $name " echo "Do you wish to continue?" read again done echo "Bye-Bye"

А теперь результат работы скрипта:

Ite@ite-desktop:~$ ./bash2_primer1.sh Please enter a name: ite The name you entered is ite Do you wish to continue? yes Please enter a name: mihail The name you entered is mihail Do you wish to continue? no Bye-Bye

Как видим цикл выполняется до тех пор, пока мы не введем что-то отличное от «yes». Между do и done можно описывать любые структуры, операторы и т.п., все они будут выполнятся в цикле.Но следует быть осторожным с этим циклом, если вы запустите на выполнение в нём какую-либо команду, без изменения переменной выражения, вы можете попасть в бесконечный цикл.

Теперь об условии истинности. После while, как и в условном операторе if-then-else можно вставлять любое выражение или команду, которая возвращает код возврата, и цикл будет исполнятся до тех пор, пока код возврата = 0! Оператор »[» аналог команды test, которая проверяет истинность условия, которое ей передали.

Рассмотрим еще один пример, я взял его из книги Advanced Bash scripting. Уж очень он мне понравился Улыбка, но я его немного упростил. В этом примере мы познакомимся с еще одним типом циклов UNTIL-DO. Эта практически полный аналог цикла WHILE-DO, только выполняется пока какое-то выражение ложно.

Вот пример:

#!/bin/bash echo "Введите числитель: " read dividend echo "Введите знаменатель: " read divisor dnd =$dividend #мы будем изменять переменные dividend и divisor, #сохраним их знания в других переменных, т.к. они нам #понадобятся dvs =$divisor remainder =1 until [ "$remainder " -eq 0 ] do let "remainder = dividend % divisor" dividend =$divisor divisor =$remainder done echo "НОД чисел $dnd и $dvs = $dividend "

Результат выполнения скрипта:

Ite@ite-desktop:~$ ./bash2_primer3.sh Введите числитель: 100 Введите знаменатель: 90 НОД чисел 100 и 90 = 10

Математические операции

Команда let.

Команда let производит арифметические операции над числами и переменными.

Рассмотрим небольшой пример, в котором мы производим некоторые вычисления над введенными числами:

#!/bin/bash echo "Введите a: " read a echo "Введите b: " read b let "c = a + b" #сложение echo "a+b= $c " let "c = a / b" #деление echo "a/b= $c " let "c <<= 2" #сдвигает c на 2 разряда влево echo "c после сдвига на 2 разряда: $c " let "c = a % b" # находит остаток от деления a на b echo "$a / $b . остаток: $c "

Результат выполнения:

Ite@ite-desktop:~$ ./bash2_primer2.sh Введите a: 123 Введите b: 12 a+b= 135 a/b= 10 c после сдвига на 2 разряда: 40 123 / 12. остаток: 3

Ну вот, как видите ничего сложного, список математических операций стандартный:

Сложение
- - вычитание
* - умножение
/ - деление
** - возведение в степень
% - модуль(деление по модулю), остаток от деления

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

Например: a = a+b эквивалентно a +=b и т.д.

Работа с внешними программами при написании shell-скриптов

Для начала немного полезной теории.

Перенаправление потоков

В bash (как и многих других оболочках) есть встроенные файловые дескрипторы: 0 (stdin), 1 (stdout), 2 (stderr).

stdout - Стандартный вывод. Сюда попадает все что выводят программы
stdin - Стандартный ввод. Это все что набирает юзер в консоли
stderr - Стандартный вывод ошибок.

Для операций с этими дескрипторами, существуют специальные символы: > (перенаправление вывода), < (перенаправление ввода). Оперировать ими не сложно. Например:

cat / dev/ random > / dev/ null

перенаправить вывод команды cat /dev/random в /dev/null (абсолютно бесполезная операция ) или

ls -la > listing

записать в файл listing содержание текущего каталога (уже полезней)

Если есть необходимость дописывать в файл (при использовании »>» он заменяется), необходимо вместо »>» использовать »>>»

sudo < my_password

после просьбы sudo ввести пароль, он возьмется из файла my_password, как будто вы его ввели с клавиатуры.

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

./ program_with_error 2 > error_file

цифра 2 перед »>» означает что нужно перенаправлять все что попадет в дескриптор 2(stderr).

Если необходимо заставить stderr писать в stdout, то это можно можно след. образом:

./ program_with_error 2 >& 1

символ »&» означает указатель на дескриптор 1(stdout)

(По умолчанию stderr пишет на ту консоль, в которой работает пользователь (вернее пишет на дисплей)).

2. Конвейеры

Конвейер - очень мощный инструмент для работы с консолью Bash. Синтаксис простой:

команда1 | команда 2 - означает, что вывод команды 1 передастся на ввод команде 2

Конвейеры можно группировать в цепочки и выводить с помощью перенаправления в файл, например:

ls -la | grep "hash" | sort > sortilg_list

вывод команды ls -la передается команде grep, которая отбирает все строки, в которых встретится слово hash, и передает команде сортировке sort, которая пишет результат в файл sorting_list. Все довольно понятно и просто.

Чаще всего скрипты на Bash используются в качестве автоматизации каких-то рутинных операций в консоли, отсюда иногда возникает необходимость в обработке stdout одной команды и передача на stdin другой команде, при этом результат выполнения одной команды должен быть неким образом обработан. В этом разделе я постараюсь объяснить основные принципы работы с внешними командами внутри скрипта. Думаю что примеров я привел достаточно и можно теперь писать только основные моменты.

1. Передача вывода в переменную

Для того чтобы записать в переменную вывод какой-либо команды, достаточно заключить команду в `` кавычки, например

A = ` echo "qwerty" ` echo $a

Результат работы: qwerty

Однако если вы захотите записать в переменную список директорий, то необходимо, должным образом обработать результат для помещения данных в переменную. Рассмотрим небольшой, пример:

LIST =` find / svn/ -type d 2>/ dev/ null| awk "{FS="/"} {print $4}" | sort | uniq | tr "\n" " " ` for ONE_OF_LIST in $LIST do svnadmin hotcopy / svn/ $ONE_OF_LIST / svn/ temp4backup/ $ONE_OF_LIST done

Здесь мы используем цикл for-do-done для архивирование всех директорий в папке /svn/ с помощью команды svnadmin hotcopy(что в нашем случае не имеет никого значения, просто как пример). Наибольшй интерес вызывает строка: LIST=`find /svn/ -type d 2>/dev/null| awk "{FS=»/»} {print $4}"| sort|uniq | tr "\n" " "` В ней переменной LIST присваивается выполнение команды find, обработанной командами awk, sort, uniq,tr(все эти команды мы рассматривать не будем, ибо это отдельная статья). В переменной LIST будут имена всех каталогов в папке /svn/ пгомещенных в одну строку(для того чтобы её стравить циклу.

Как видно, все не сложно, достаточно понять принцип и написать пару своих скриптов. В заключении статьи хочу пожелать удачи в изучении BASH и Linux в целом. Критика, как водится приветствуется. Следующая статья возможно будет посвящена использованию таких программ как sed, awk.




Top