<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mysyslog.ru &#187; scripting</title>
	<atom:link href="http://mysyslog.ru/posts/tag/scripting/feed" rel="self" type="application/rss+xml" />
	<link>http://mysyslog.ru</link>
	<description>Всякая IT всячина</description>
	<lastBuildDate>Sat, 17 Mar 2012 17:39:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Обработка сигналов в sh</title>
		<link>http://mysyslog.ru/posts/621</link>
		<comments>http://mysyslog.ru/posts/621#comments</comments>
		<pubDate>Thu, 02 Dec 2010 14:39:58 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[sh]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=621</guid>
		<description><![CDATA[Сигналы &#8211; один из способов взаимодействия между процессами. Отправив определенный сигнал, можно приостановить или возобновить работы приложения, завершить его или сделать с ним еще что-нибудь. Сигнал определяется номером, которому соответствие имя. Посмотрите man signal или наберите kill -l чтобы получить список сигналов.
В скриптах обработка сигналов может быть крайне полезна.

 Например, ваш скрипт выполняет обновление системы [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Сигналы</strong> &#8211; один из способов взаимодействия между процессами. Отправив определенный сигнал, можно приостановить или возобновить работы приложения, завершить его или сделать с ним еще что-нибудь. Сигнал определяется номером, которому соответствие имя. Посмотрите <strong>man signal</strong> или наберите <strong>kill -l</strong> чтобы получить список сигналов.<br />
В скриптах обработка сигналов может быть крайне полезна.<br />
<span id="more-621"></span><br />
 Например, ваш скрипт выполняет обновление системы и тут происходит разрыв соединения с сервером&#8230; что получится в результате сказать сложно, скорее всего ничего хорошего. Конечно же можно запустить процесс через <strong>nohup</strong>, но можно поступить иначе &#8211; вписать обработку сигналов.<br />
 Или другой пример, скрипт в течение своей работы создает временные файлы, которые потом удаляются, но при нажатии <strong>Ctrl+С</strong> он завершит свою работу сразу и никакой чистки данных выполнять не будет. Но если обработать сигнал, то можно завершить работы скрипта куда элегантнее.<br />
Для обработки сигналов в sh используется встроенная команда trap, формат ее такой</p>
<pre class="brush: plain;">trap [action] signal ...</pre>
<p>Т.е. команде нужно передать как минимум два параметра, действие при получении сигнала и сигнал, для которого будет выполняться указанное действие. Сигналов можно указать несколько подряд. В качестве пример напишем скрипт, которые при получении SIGHUP будет продолжать работать. Т.е. при закрытии консоли, в которое выполняется наш скрипт, он спокойно продолжит выполнение, а не завершится. При получении SIGINT скрипт удалит временные файлы и завершит работу, SIGINIT вызывается при нажатии Ctrl+C.</p>
<pre class="brush: bash;">
#!/bin/sh

TEMPFILE=`mktemp /tmp/XXXXXXX`

signalhandler() {
  local signal=$1

  case $signal in
    SIGHUP)
      echo &quot;Do nothing&quot;
    ;;
    SIGINT)
      rm -f $TEMPFILE
      exit
    ;;
  esac
}

trap &quot;signalhandler SIGINT &quot;  SIGINT
trap &quot;signalhandler SIGHUP &quot;  SIGHUP

# do something good

rm -f $TEMPFILE
exit 0
</pre>
<p>Для обработки сигналов используется наша функция <strong>signalhandler</strong>, которая в качестве параметра принимает имя сигнала, и в зависимости от него выполняет разные действия. Чтобы передать разные имена сигналов приходится вызывать trap несколько раз.<br />
Как видите, все просто. </p>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/621/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sed tips and tricks</title>
		<link>http://mysyslog.ru/posts/598</link>
		<comments>http://mysyslog.ru/posts/598#comments</comments>
		<pubDate>Wed, 24 Nov 2010 16:06:20 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Новости]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=598</guid>
		<description><![CDATA[Sed &#8211; прекрасное средство редактирования текста с отвратительной документацией. В скриптах он часто бывает незаменим, но чтобы выполнить что-то непривычное приходится долго искать интернете нужный пример или долго экспериментировать с разными вариантами. Очень неудобно!
Так что сделаю сделаю себе памятку!

1) Разделители в sed
Часто нужно поменять какие-то пути в файлах и выглядит это страшно, примерно так:
echo $PATH [...]]]></description>
			<content:encoded><![CDATA[<p>Sed &#8211; прекрасное средство редактирования текста с отвратительной документацией. В скриптах он часто бывает незаменим, но чтобы выполнить что-то непривычное приходится долго искать интернете нужный пример или долго экспериментировать с разными вариантами. Очень неудобно!<br />
Так что сделаю сделаю себе памятку!<br />
<span id="more-598"></span><br />
<strong>1) Разделители в sed</strong><br />
Часто нужно поменять какие-то пути в файлах и выглядит это страшно, примерно так:</p>
<pre class="brush: bash;">echo $PATH | sed s'/\/etc/\/usr\/local\/etc/g'</pre>
<p>Читать это невозможно, да и ошибиться с экранирование легче легкого!<br />
На самом деле sed воспринимает и другие символы в качестве разделителей, а использование &#8216;/&#8217; является &#8220;исторической традицией&#8217;. Данную конструкцию легко заменить на такую:</p>
<pre class="brush: bash;">echo $PATH | sed s':/etc:/usr/local/etc:g'</pre>
<p>Или такую:</p>
<pre class="brush: bash;">echo $PATH | sed s'|/etc|/usr/local/etc|g'</pre>
<p>Согласитесь, так намного лучше!</p>
<p>2) <strong>Выполнение нескольких команд sed подряд</strong><br />
Иногда нужно выполнить несколько команд подряд, самый простой способ &#8211; сделать несколько pipe, но выглядит это так себе.</p>
<pre class="brush: bash;">echo &quot;New string&quot; | sed 's/New/Old/' | sed 's/string/letter/'</pre>
<p>Вместо этого можно задать последовательность при помощи опции <strong>-e</strong>:</p>
<pre class="brush: bash;">echo &quot;New string&quot; | sed -e 's/New/Old/' -e 's/string/letter/'</pre>
<p>Или можно задать последовательность команд через &#8216;;&#8217;:</p>
<pre class="brush: bash;">echo &quot;New string&quot; | sed 's/New/Old/; s/string/letter/'</pre>
<p>3) <strong>Экранирование команд sed в разных оболочках</strong><br />
Очень важная тема, особенно в контексте написания скриптов. Например если <strong>/bin/csh</strong> ввести такую команду:</p>
<pre class="brush: bash;">cat /etc/resolv.conf | sed /search/ a\
nameserver 127.0.0.1 \
'
sed: 1: &quot;/search/ a
1 ...&quot;: command a expects \ followed by text
</pre>
<p>Получаем неприятную ошибку вместо ожидаемого результата. Решение &#8211; добавить еще один &#8216;\&#8217; после &#8216;a\&#8217;:</p>
<pre class="brush: bash;">cat /etc/resolv.conf | sed /search/ a\ \
nameserver 127.0.0.1 \
'
</pre>
<p>В общем случае для <strong>sed в C shell</strong> экранировать нужно так:</p>
<pre class="brush: bash;">
#!/bin/csh -f
sed 's/a/A/g \
s/e/E/g \
s/i/I/g \
s/o/O/g \
s/u/U/g' &lt;old&gt;new
</pre>
<p>Для <strong>Bash</strong> все проще:</p>
<pre class="brush: bash;">
#!/bin/sh
sed '
s/a/A/g
s/e/E/g
s/i/I/g
s/o/O/g
s/u/U/g' &lt;old &gt;new
</pre>
<p>4) <strong>Основные команды sed</strong></p>
<table style="height: 17px;" border="0" width="129">
<tbody>
<tr>
<td>Команда</td>
<td>Описание</td>
</tr>
<tr>
<td>p</td>
<td>Вывести адресуемую строку</td>
</tr>
<tr>
<td>=</td>
<td>Вывести адреса адресуемых строк</td>
</tr>
<tr>
<td>a</td>
<td>Добавление текста после адресуемой строки</td>
</tr>
<tr>
<td>i</td>
<td>Добавление текста перед адресуемой строкой</td>
</tr>
<tr>
<td>с</td>
<td>Замена адресуемой строки блоком указанного текста</td>
</tr>
<tr>
<td>d</td>
<td>Удаление адресуемой строки</td>
</tr>
</tbody>
</table>
<p>Собственно они есть в любом нормальном описании по sed, здесь я их привожу, как шпаргалку и за одно несколько примеров.<br />
Поиск номера строки по определенному шаблону, опция -n запрещает вывод всех остальных строк:</p>
<pre class="brush: bash;">cat /path/to/file | sed -n '/some/='</pre>
<p>Поиск строки по шаблону:</p>
<pre class="brush: bash;">cat /path/to/file | sed -n '/some/p'</pre>
<p>Удалим все строки со словом some из файла /path/to/file:</p>
<pre class="brush: bash;">sed -I '' -e '/some/d' /path/to/file</pre>
<p>Удалим строки с первой по третью:</p>
<pre class="brush: bash;">sed -I '' -e '1,3d' /path/to/file</pre>
<p>Удалим последнюю строку</p>
<pre class="brush: bash;">sed -I '' -e '$d' /path/to/file</pre>
<p>Опция -I нужна для редактирования указанного файла, а параметр &#8221; говорит, что не нужно создавать резервную копию.<br />
Добавление и изменение строк работает аналогично.</p>
<p>5) <strong>Хорошая документация по sed</strong><br />
В принципе для какого-то просто скриптинга всех этих приемов более чем хватает, но всегда может получить больше, например на <a href="http://www.grymoire.com/Unix/Sed.html">сайте</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/598/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>значение по умолчанию для переменной shell</title>
		<link>http://mysyslog.ru/posts/554</link>
		<comments>http://mysyslog.ru/posts/554#comments</comments>
		<pubDate>Wed, 03 Nov 2010 09:09:29 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[sh]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=554</guid>
		<description><![CDATA[Иногда нужно выставить значение по умолчанию для переменной, которую может указать/не указать пользователь в качестве аргумента при запуске. Для этого можно использовать вот такую конструкцию:

VALUE=''
VALUE_DEFAULT='default'

if [ -z $VALUE ]; then
  VALUE=&#34;$VALUE_DEFAULT&#34;
fi

echo $VALUE

Из явных плюсов &#8211; ее читабельность, как всегда в ущерб краткости. Пробуем написать тоже самое, но короче:

VALUE='1'
VALUE_DEFAULT='default'

[ -z $VALUE ] &#38;&#38; VALUE=&#34;$VALUE_DEFAULT&#34;

echo $VALUE

Получилось, [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда нужно выставить значение по умолчанию для переменной, которую может указать/не указать пользователь в качестве аргумента при запуске. Для этого можно использовать вот такую конструкцию:</p>
<pre class="brush: bash;">
VALUE=''
VALUE_DEFAULT='default'

if [ -z $VALUE ]; then
  VALUE=&quot;$VALUE_DEFAULT&quot;
fi

echo $VALUE
</pre>
<p>Из явных плюсов &#8211; ее читабельность, как всегда в ущерб краткости. Пробуем написать тоже самое, но короче:</p>
<pre class="brush: bash;">
VALUE='1'
VALUE_DEFAULT='default'

[ -z $VALUE ] &amp;&amp; VALUE=&quot;$VALUE_DEFAULT&quot;

echo $VALUE
</pre>
<p>Получилось, но теперь понять конструкцию чуть сложнее. Пробуем сделать еще более короткий вариант:</p>
<pre class="brush: bash;">
VALUE=''
VALUE_DEFAULT='default'

VALUE=${VALUE:-$VALUE_DEFAULT}

echo $VALUE
</pre>
<p>Самый короткий вариант, но понятный только тем, кто внимательно прочитал man sh.</p>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/554/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Вывод сообщения в stderr из shell скрипта</title>
		<link>http://mysyslog.ru/posts/506</link>
		<comments>http://mysyslog.ru/posts/506#comments</comments>
		<pubDate>Tue, 01 Jun 2010 10:46:25 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=506</guid>
		<description><![CDATA[Очень полезная вещь &#8211; перенаправление потоков вывода. С ее помощью в shell скриптах можно сделать многое, в том числе и вывод сообщений в stderr. Пример простого скрипта ниже:

#/bin/sh

DEBUG=0

print_debug()
{
  if [ &#34;x$DEBUG&#34; != &#34;x0&#34; ]; then
    echo $* &#62;&#38;2
  fi
}

print_debug hello world

Переменная DEBUG, если не равно 0, указывает, что нужно выводить [...]]]></description>
			<content:encoded><![CDATA[<p>Очень полезная вещь &#8211; перенаправление потоков вывода. С ее помощью в shell скриптах можно сделать многое, в том числе и вывод сообщений в stderr. Пример простого скрипта ниже:</p>
<pre class="brush: bash;">
#/bin/sh

DEBUG=0

print_debug()
{
  if [ &quot;x$DEBUG&quot; != &quot;x0&quot; ]; then
    echo $* &gt;&amp;2
  fi
}

print_debug hello world
</pre>
<p>Переменная DEBUG, если не равно 0, указывает, что нужно выводить сообщения в функции print_debug. Обычное echo выводи строку со всеми аргументами функции (переменная $*) в stdout, которые перенаправляется в stderr ( >&#038;2 ). </p>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/506/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Правильный и красивый способ добавлять модули ядра в автозагрузку в CentOS 5.X</title>
		<link>http://mysyslog.ru/posts/426</link>
		<comments>http://mysyslog.ru/posts/426#comments</comments>
		<pubDate>Tue, 20 Apr 2010 09:07:24 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=426</guid>
		<description><![CDATA[Наткнулся на блог с красивым и правильным методом добавления модулей в автозагрузку centos 5.x.

Все уже есть в самой системе и, как всегда, не нужно изобретать велосипед =) В файле /etc/rc.sysinit есть вот такая конструкция:

# Load other user-defined modules
for file in /etc/sysconfig/modules/*.modules ; do
  [ -x $file ] &#38;&#38; $file
done

Т.е. для добавления модуля достаточно создать [...]]]></description>
			<content:encoded><![CDATA[<p>Наткнулся на <a href="http://purpleblog.wordpress.com/2008/06/25/centos-modules-autoload/">блог</a> с красивым и правильным методом добавления модулей в автозагрузку centos 5.x.<br />
<span id="more-426"></span><br />
Все уже есть в самой системе и, как всегда, не нужно изобретать велосипед =) В файле /etc/rc.sysinit есть вот такая конструкция:</p>
<pre class="brush: bash;">
# Load other user-defined modules
for file in /etc/sysconfig/modules/*.modules ; do
  [ -x $file ] &amp;&amp; $file
done
</pre>
<p>Т.е. для добавления модуля достаточно создать файл some_name.modules в каталоге /etc/sysconfig/modules/, внутри которого будет команда на его загрузку. Что-то такое:</p>
<pre class="brush: plain; light: true;">
# cat /etc/sysconfig/modules/some_name.modules
modprobe some_module
</pre>
<p>Попробуем автоматизировать процесс добавления/удаление/просмотра модулей, для этого пишем скрипт:</p>
<pre class="brush: bash;">
#!/bin/sh

check_action ()
{
        if [ $ACTION != &quot;list&quot; ] &amp;&amp; [ $ACTION != &quot;add&quot; ] &amp;&amp; [ $ACTION != &quot;del&quot; ]; then
                show_help
                exit 1
        fi
}

show_help ()
{
        echo Usage: `basename $0` ACTION [ MODULE_NAME ]
        echo ACTION - list\|add\|del
        echo MODULE_NAME - module name for add\|del ACTION
}

make_action ()
{
        case $ACTION in
                &quot;list&quot;)
                        for i in `find $WORKDIR -type f -name &quot;*.modules&quot;`; do
                                module=`echo $i|sed 's/\.modules//'`
                                echo `basename $module`
                        done
                ;;
                &quot;add&quot;)
                        echo &quot;modprobe $MODULE_NAME&quot; &gt; $WORKDIR/$MODULE_NAME.modules
                        chmod 750 $WORKDIR/$MODULE_NAME.modules
                ;;
                &quot;del&quot;)
                        rm -f $WORKDIR/$MODULE_NAME.modules
                ;;

        esac
}

ACTION=&quot;$1&quot;
MODULE_NAME=&quot;$2&quot;
WORKDIR=&quot;/etc/sysconfig/modules/&quot;
: ${ACTION:=&quot;list&quot;}

check_action
make_action
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/426/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jot и seq или как упростить себе работы с циклами</title>
		<link>http://mysyslog.ru/posts/280</link>
		<comments>http://mysyslog.ru/posts/280#comments</comments>
		<pubDate>Mon, 01 Mar 2010 10:17:57 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=280</guid>
		<description><![CDATA[jot (FreeBSD)
seq (Linux)
две простые утилиты для работы с последовательностями, прекрасная альтернатива замены for в shell скриптах.

Работать с ними очень просто:

SEQ=`jot 10 1 10`
for i in $SEQ
 echo $i
done

Получим

1
2
3
4
5
6
7
8
9
10

А если вот так, то

SEQ=`jot 10 10 1`


10
9
8
7
6
5
4
3
2
1

Первая[10] цифра, это число цифр, которые нужно напечатать, вторая[1] &#8211; первый элемент, третья[10] &#8211; последний элемент. Т.е. jot сам построит последовательность [...]]]></description>
			<content:encoded><![CDATA[<p>jot (FreeBSD)<br />
seq (Linux)<br />
две простые утилиты для работы с последовательностями, прекрасная альтернатива замены for в shell скриптах.<br />
<span id="more-280"></span><br />
Работать с ними очень просто:</p>
<pre class="brush: bash; light: false;">
SEQ=`jot 10 1 10`
for i in $SEQ
 echo $i
done
</pre>
<p>Получим</p>
<pre class="brush: bash; light: true;">
1
2
3
4
5
6
7
8
9
10
</pre>
<p>А если вот так, то</p>
<pre class="brush: bash; light: false;">
SEQ=`jot 10 10 1`
</pre>
<pre class="brush: bash; light: true;">
10
9
8
7
6
5
4
3
2
1
</pre>
<p>Первая[10] цифра, это число цифр, которые нужно напечатать, вторая[1] &#8211; первый элемент, третья[10] &#8211; последний элемент. Т.е. jot сам построит последовательность из 10 цифр с равным шагом, чтобы пройтись от 1 до 10.</p>
<p>seq в Linux несколько проще, </p>
<pre class="brush: bash; light: false;">
seq FIRST INCREMENT LAST
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/280/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

