По программированию на shell существует много пособий и учебников, но в этой статье я хотел бы поговорить о нескольких приемах, которые часто либо не используются, либо воспринимаются неправильно. Особенно это касается новичков в shell программировании
1. Создание lock файла
Очень часто нужно бывает выполнять скрипт, который может делать непредсказуемые вещи, если его запустить параллельно. Особенно часто это бывает, когда скрипт запускается из cron, а предыдущий его экземпляр не успел завершиться.
Вот пример скрипта, который создает lock файл, и если он присутствует — то вылетает с ошибкой.
| Код: |
| #!/bin/sh LOCKFILE=/tmp/mylockif [ ! –s $LOCKFILE ]; then # проверяем, что lock файл пустой echo $$ > $LOCKFILE # записываем идентификатор процесса в lock файл # все действия скрипта нужно поместить здесь : > $LOCKFILE # обнуляем lock файл exit 0 else # как пример — отсылаем почту root, из-за того, # что не скрипт не может быть запущен echo “PID `cat $LOCKFILE` running” | mailx –s “$0 can’t run” root exit 1 fi |
Этот скрипт можно переписать, чтоб он пытался бы запуститься несколько раз с паузами (просто добавить while и sleep), либо чтоб он убивал бы ранее запущенный скрипт, если тот выполняется более N секунд.
2. ВСЕГДА проверяйте коды возврата
Всегда проверяйте, какой код возврата вам выдала запущенная вами программа или скрипт — так как это может повлиять на дальнейшую работу вашего скрипта. В /bin/sh код возврата находится в переменной $? .
3.Используйте код возврата
Вы можете проанализировать код возврата при помощи команды test (используя ее в виде квадратных скобок [ ] ) и выполнить правильную последовательность действий
| Код: |
| if [ “$?” -eq ‘0’ ]; then echo ‘Я зиданчег’; else echo ‘Я не зиданчег’; fi |
Не забывайте, что в shell положительный код возврата это 0, а все оставшиеся коды — это сообщение об ошибках.
Можно сразу передавать команды оператору if, а не анализировать код выхода, сохраненный в $?.
| Код: |
| host=’127.0.0.1′ if ping -c 1 $host; then echo ‘Хост пингуецца’; else echo ‘Хост совсем неживой’; fi |
4. Объединение вывода команд
Можно объединять вывод нескольких команд вместе. Вместо того, чтоб добавлять вывод нескольких команд в один и тот-же файл, можно использовать subshell — дочерний shell.
| Код: |
| #!/bin/sh ( echo ‘———————–’ cat /etc/motd echo ‘———————–’ cat /etc/issue echo ‘———————–’ ) > /tmp/motd-issue |
5.Другие приемы с subshell
При выполнении цепочки команд может быть очень полезным сперва поменять директорию, а потом только выполнять команду. Вот как это делается
| Код: |
| tar cf - . | (cd /tmp/test && tar xpf -) |
Если директории /tmp/test не существует, то и вторая команда tar не будет выполнена.
6.Запуск куска кода в фоновом режиме
Если вам нужно запустить кусок кода в фоновом режиме, то тоже можно использовать subshell
| Код: |
| #!/bin/sh echo ‘begin’ (echo ’subshell start’; sleep 5; echo ’subshell stop’)& echo ‘end’ |
Кусочек кода (echo ’subshell start’; sleep 5; echo ’subshell stop’) будет выполняться в фоновом режиме до тех пор, пока не завершиться.
7.Использование команд через ssh
Есть огромное количество ситуаций, когда очень удобно пересылать данные и команды через ssh. Например, чтоб скопировать файлы и директории с одного компьютера на другой:
| Код: |
| tar cf - ./dir | ssh $host “cd /dir/ && tar xpf –“ |
Или как вариант, запустить скрипт на удаленном хосте, не копируя его туда:
| Код: |
| cat script.sh | ssh $host /bin/sh |
Понравилось? Подпишись на RSS!
Хочешь написать статью? Мы ищем авторов (и не только за красивые глаза, но и за дохлых президентов).

>tar cf - ./dir | ssh $host “cd /dir/ && tar xpf –“
Прикольно! Не приходило в голову :)