<?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>sveshnikov.ru - это наилучший источник информации по теме unix perl shell и всего такого &#187; загогулины</title>
	<atom:link href="http://alexey.sveshnikov.ru/blog/category/%d0%b7%d0%b0%d0%b3%d0%be%d0%b3%d1%83%d0%bb%d0%b8%d0%bd%d1%8b/feed/" rel="self" type="application/rss+xml" />
	<link>http://alexey.sveshnikov.ru/blog</link>
	<description>bookmarks-on-tranquilizers</description>
	<lastBuildDate>Tue, 25 May 2010 20:30:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Восхитительные грабли.</title>
		<link>http://alexey.sveshnikov.ru/blog/2010/04/28/shell_rake/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2010/04/28/shell_rake/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 19:34:08 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[PERL]]></category>
		<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[загогулины]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=171</guid>
		<description><![CDATA[Я недавно открыл для себя восхитительные грабли. Оказывается, что я ходил по ним годами, а наступил только вчера. Допустим, нам нужно скачать какой-нибудь файлик из сети, посчитать его размер и сохранить в файл. Код на perl будет примерно таким: #!/usr/bin/perl -w use strict; if (system('wget -O- http://sveshnikov.ru/httpd.sh &#124; wc -с > /tmp/size') != 0) { [...]]]></description>
			<content:encoded><![CDATA[<p>Я недавно открыл для себя восхитительные грабли. Оказывается, что я ходил по ним годами, а наступил только вчера.</p>
<p>Допустим, нам нужно скачать какой-нибудь файлик из сети, посчитать его размер и сохранить в файл.</p>
<p>Код на perl будет примерно таким:</p>
<p><code><br />
#!/usr/bin/perl -w<br />
use strict;</p>
<p>if (system('wget -O- http://sveshnikov.ru/httpd.sh | wc -с > /tmp/size') != 0) {<br />
        die "OMG! Can't count bytes in httpd.sh file!!!";<br />
}<br />
</code></p>
<p>В дальнейшем этот скрипт используется примерно так: if ./get_value; then <em>работаем с /tmp/size</em>; else <em>сообщаем куда нужно</em>; fi</p>
<p>Так вот, у этого скрипта хромает надежность. Почему? И как это сделать правильно? Жду ваших вариантов, мой &#8211; завтра :)</p>
<p><strong>UPD:</strong></p>
<p>Проблема заключается в том, что при использовании пайпов в $? окажется результат последней выполненной команды:<br />
<code><br />
$ blablabla | wc; echo $?<br />
zsh: command not found: blablabla<br />
      0       0       0<br />
0<br />
</code></p>
<p>Я решил этот вопрос с помощью bash и его опции pipefail. Пример выше я бы переписал как-то так:</p>
<p><code><br />
#!/usr/bin/perl -w<br />
use strict;                                                                                                                                                                    </p>
<p>sub my_system {<br />
      return system('bash', '-o', 'pipefail', '-c', @_);<br />
}                                                                                                                                                                              </p>
<p>unless (my_system('wget -O- http://sveshnikov.ru/httpd.sh | wc > /tmp/size') == 0) {<br />
      die "OMG! Can't count bytes in httpd.sh file!!!";<br />
}<br />
</code></p>
<p>Теперь будут отлавливаться все ошибки.<br />
В шелл-скриптах можно еще анализировать массив PIPESTATUS, в котором сохраняется exit code для всех команд ковейера, но мне показалось, что это неудобно.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2010/04/28/shell_rake/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Пятничная загогулина (bash)</title>
		<link>http://alexey.sveshnikov.ru/blog/2008/04/11/zagogulina-bash-read/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2008/04/11/zagogulina-bash-read/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 09:41:07 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[загогулины]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[загогулина]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/2008/04/11/%d0%b7%d0%b0%d0%b3%d0%be%d0%b3%d1%83%d0%bb%d0%b8%d0%bd%d0%b0-%d0%bd%d0%b0-bash/</guid>
		<description><![CDATA[Ну вот, пришло время для очередной программерской загогулины. Следующий код работать не будет: #!/usr/bin/bash echo "one two three" &#124; read a b c echo " " Что в нем не так? Я ожидаю увидеть два ответа. Первый &#8212; это просто переписать этот код так, чтобы он заработал. И второй ответ &#8212; опционально &#8212; объяснение, почему [...]]]></description>
			<content:encoded><![CDATA[<p>Ну вот, пришло время для очередной программерской загогулины. Следующий код работать не будет:</p>
<p><code>#!/usr/bin/bash<br />
echo "one two three" | read a b c<br />
echo "<$a> <$b> <$c>"</code></p>
<p>Что в нем не так?</p>
<p>Я ожидаю увидеть два ответа. Первый &#8212; это просто переписать этот код так, чтобы он заработал. И второй ответ &#8212; опционально &#8212; объяснение, почему не работает в таком виде.</p>
<p>p.s. второго ответа я пока сам не знаю, поэтому буду с интересом ждать его от вас :)<br />
p.p.s. ответивший верно, как всегда &#8211; умничка (-ца (маловероятно)).</p>
<p><b>UPD:</b> На второй вопрос ответ уже есть:<br />
<quote>gds<br />
есть мнение, что переменные, прочитанные read, остаются в переменных “экземпляра” баша, запущенного для выполнения “read a b c”, и не попадают в родительский баш, запустивший “echo … | read a b c”.</quote></p>
<p>gds&#8217;у &#8211; респект!<br />
А я понял, что в следующий раз надо постить задачки посложнее.. </p>
<p><b>UPD2</b> <s>свое решение выложу сегодня в конце рабочего дня</s><br />
<b>UPD3</b> </p>
<p>Кажется, я нечаянно сорвал рабочий день моего <a href="http://curved-hands.blogspot.com">начальника</a>, но зато он мне прислал вот такое остроумное решение:<br />
<code>str=`echo "one two three" | (read a b c; echo "a=$a; b=$b; c=$c;") `<br />
eval "$str";<br />
echo "<$a> <$b> <$c>"</code></p>
<p>Петя, ты отжог :) </p>
<p>Но на самом деле все это можно сделать несколько проще &#8211; через &#8220;here doc&#8221;:<br />
<code>read a b c  <<<`echo "one two three"`<br />
echo "<$a> <$b> <$c>"</code></p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2008/04/11/zagogulina-bash-read/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Загадка!</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/10/19/%d0%b7%d0%b0%d0%b3%d0%b0%d0%b4%d0%ba%d0%b0/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/10/19/%d0%b7%d0%b0%d0%b3%d0%b0%d0%b4%d0%ba%d0%b0/#comments</comments>
		<pubDate>Fri, 19 Oct 2007 11:40:43 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[загогулины]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[zagogulina]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/2007/10/19/%d0%b7%d0%b0%d0%b3%d0%b0%d0%b4%d0%ba%d0%b0/</guid>
		<description><![CDATA[&#8220;Если достаточно долго лазить по карманам своих курток, можно найти практически любую сумму денег&#8221; (народная мудрость). Вот и с задачками примерно такая же ситуация &#8211; вспомнил весьма любопытную. Приятно, знаете ли, иногда посмотреть как люди мучаются над задачками, которые когда-то серьезно озаботили тебя самого :) Итак, есть следующий код: #!/bin/sh get_size() { if [ "`uname`" [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Если достаточно долго лазить по карманам своих курток, можно найти практически любую сумму денег&#8221; (народная мудрость). Вот и с задачками примерно такая же ситуация &#8211; вспомнил весьма любопытную.<br />
Приятно, знаете ли, иногда посмотреть как люди мучаются над задачками, которые когда-то серьезно озаботили тебя самого :)</p>
<p>Итак, есть следующий код:</p>
<p><code>#!/bin/sh</p>
<p>get_size() {<br />
    if [ "`uname`" = "FreeBSD" ]; then<br />
        r=`stat -f %z $1`<br />
    else<br />
        r=`stat -c %s $1`<br />
    fi<br />
    return $r<br />
}</p>
<p>if [ -z $1 ]; then<br />
    echo "usage: print_size <file_name>";<br />
else<br />
    get_size $1;<br />
    echo $?<br />
fi<br />
</code></p>
<p>Вот результат работы скрипта:<br />
<code>asveshnikov@fe08a023fb1cc27a:~/tmp$ ls -la<br />
total 112<br />
drwxr-xr-x  2 asveshnikov asveshnikov  4096 2007-10-19 15:38 .<br />
drwxr-xr-x 85 asveshnikov asveshnikov  8192 2007-10-19 13:15 ..<br />
-rw-r--r--  1 asveshnikov asveshnikov 39781 2007-08-29 15:22 DSC02473.jpg<br />
-rw-r--r--  1 asveshnikov asveshnikov 49553 2007-08-31 17:41 DSC02481.jpg<br />
-rwxr-xr-x  1 asveshnikov asveshnikov   231 2007-10-19 15:27 print_size.sh<br />
asveshnikov@fe08a023fb1cc27a:~/tmp$ ./print_size.sh print_size.sh<br />
231<br />
asveshnikov@fe08a023fb1cc27a:~/tmp$ ./print_size.sh DSC02473.jpg<br />
39781</code></p>
<p>Как видите, абсолютно рабочий код, проверялся в Linux и FreeBSD.<br />
При этом он имеет просто ужасную.. нет, <b>чудовищную</b> проблему переносимости, которую при некоторых обстоятельствах крайне сложно обнаружить в скриптах несколько большего размера &#8211; какую?</p>
<p>p.s. угадавший первым будет умничкой :)</p>
<p>UPD: </p>
<p>Уже двое человек указали на то, что `uname` желательно взять еще и в кавычки. Вобщем, предлагаю не мелочиться, здесь проблема если и есть, то явно не &#8220;чудовищная&#8221;. Чтобы больше никого не смущать этим, подправил код. </p>
<p>Решено!</p>
<p>Михаил достаточно подробно описал проблему:</p>
<blockquote><p>Если не брать в голову отсутствие кавычек вокруг $1, а также неполный способ определения размера файла (под солярой нет stat, например), то мне кажется основная проблема в возврате значения из функции. На самом деле таким образом можно вернуть только целое, причем очень ограниченное, так как по сути возвращается код завершения функции (если не изменяет память &#8211; максимум &#8211; 256). таким образом на больших файлах получим неверное значение.</p>
<p>Решением может служить использование для возврата глобальное переменной, либо через echo.</p></blockquote>
<p>С моей стороны осталось лишь пояснить, почему проблема является &#8220;чудовищной&#8221; &#8211; она запросто может привести к порче данных, так как никакие сообщения об ошибках выводиться не будут. Ну и выглядит внешне этот код вполне надежным, так что отлавливать такой баг может быть задачей не из легких.</p>
<p>Собственно, основные проблемы возникают при портировании скрипта с sh на bash:</p>
<p><code>asveshnikov@fe08a023fb1cc27a:~/tmp$ ls -al DSC02473.jpg<br />
-rw-r--r-- 1 asveshnikov asveshnikov 39781 2007-08-29 15:22 DSC02473.jpg<br />
asveshnikov@fe08a023fb1cc27a:~/tmp$ bash print_size.sh DSC02473.jpg<br />
101</code></p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/10/19/%d0%b7%d0%b0%d0%b3%d0%b0%d0%b4%d0%ba%d0%b0/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Программерские загогулины [2]</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/08/23/zagogulina2/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/08/23/zagogulina2/#comments</comments>
		<pubDate>Thu, 23 Aug 2007 16:51:12 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[загогулины]]></category>
		<category><![CDATA[общее]]></category>
		<category><![CDATA[quiz]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=23</guid>
		<description><![CDATA[Очередная программерская загогулина, на этот раз решение сразу не дам :) Допустим, надо выполнить какую-либо команду на нескольких хостах, перечисленных в файле. Пишу: cat file &#124; ( while read host; do ssh user@$host "command" done ) Ошибка, однако! В чем? Кто сможет разобраться в уме, не запуская код, тому респект и уважуха :) UPD: Решил [...]]]></description>
			<content:encoded><![CDATA[<p>Очередная программерская загогулина, на этот раз решение сразу не дам :)</p>
<p>Допустим, надо выполнить какую-либо команду на нескольких хостах, перечисленных в файле. Пишу:</p>
<p><code>cat file | (<br />
   while read host; do<br />
      ssh user@$host "command"<br />
   done<br />
)</code></p>
<p>Ошибка, однако! В чем?<br />
Кто сможет разобраться в уме, не запуская код, тому респект и уважуха :)</p>
<p><b>UPD: </b></p>
<p>Решил человек, скрывающийся под ником gds:</p>
<blockquote><p>поток из “cat file” будет выкушан только первой запущенной командой “ssh …”?</p></blockquote>
<p>gds, респект тебе уважуха  :)</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/08/23/zagogulina2/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>codepage horror</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/06/29/codepage-horror/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/06/29/codepage-horror/#comments</comments>
		<pubDate>Thu, 28 Jun 2007 20:01:54 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[загогулины]]></category>
		<category><![CDATA[общее]]></category>
		<category><![CDATA[SHELL]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=27</guid>
		<description><![CDATA[Иногда мне снятся сны. Бывает, что кошмары. Что такое кошмар для админа? Это когда видишь свой сайт &#8211; все работает, все грузится, но кодирЛЮХВ КВЯНЕК ЗИЕОЕИВ!!! На работе сегодня этот кошмар воплотился: вселился бес в базу и попутал все кодировки. Попутал на славу, так что первый дамп пришлось расшифровать в два приема: utf8->koi и cp1251->koi, [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда мне снятся сны. Бывает, что кошмары. Что такое кошмар для админа? Это когда видишь свой сайт &#8211; все работает, все грузится, но кодирЛЮХВ КВЯНЕК ЗИЕОЕИВ!!!</p>
<p>На работе сегодня этот кошмар воплотился: вселился бес в базу и попутал все кодировки. Попутал на славу, так что первый дамп пришлось расшифровать в два приема: utf8->koi и cp1251->koi, а со вторым развлечение было поизощреннее. С каждой перестановкой буквы прыгали издевательски с места на место, подмигивали и смеялись, доводя мой <s>ЙЛЗХ</s>моск до кипения. Но битву они все-так проиграли. После пятой перекодировки cp1251->koi8r из поганцев сгинул злой дух и оборотились они текстом складным и залился дамп в базу и вернулись: юзерам &#8211; счастье, а админу &#8211; крепкий сон :)</p>
<p>p.s.</p>
<p>А на #freebsd народ показал такой фокус:</p>
<p><code><br />
#str="трали-вали"; for((i=0; $i<20; i++)); do str=`echo "$str" | iconv -f CP1251 -t KOI8-R`; done;<br />
#echo $str<br />
трали-вали<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/06/29/codepage-horror/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>return 0;</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/06/27/im-back/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/06/27/im-back/#comments</comments>
		<pubDate>Wed, 27 Jun 2007 19:45:17 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[PERL]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[загогулины]]></category>
		<category><![CDATA[quiz]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=26</guid>
		<description><![CDATA[Я вернулся :) За время учебного отпуска нагулял отличное рабочее настроение! В первый рабочий день обратил внимание на небольшой юбилей: 1 год и 4 дня исполнилось моему процессу screen, запущенному на работе, которым я активно пользуюсь по 40 часов в неделю. Слава героям!! Попутно веду свою маленькую коллекцию программерских загогулин, вот очередной экземпляр: #!/usr/bin/perl $var1 [...]]]></description>
			<content:encoded><![CDATA[<p>Я вернулся :)<br />
За время учебного отпуска нагулял отличное рабочее настроение!</p>
<p>В первый рабочий день обратил внимание на небольшой юбилей: 1 год и 4 дня исполнилось моему процессу screen, запущенному на работе, которым я активно пользуюсь по 40 часов в неделю. Слава героям!!</p>
<p>Попутно веду свою маленькую коллекцию программерских загогулин, вот очередной экземпляр:</p>
<p><code><br />
#!/usr/bin/perl<br />
$var1 = "one|two|three";<br />
$var2 = join('|', split ('|', $var1));<br />
</code></p>
<p>Опрос знакомых программистов показал, что предполагаемым значением $var2 является исходная строка  ($var1). PERL думает иначе.</p>
<p>Вся мощь перла с его реально перегруженными функциями именно в этом моменте дала слабину: split в качестве первого аргумента принимает _только_ регулярное выражение, и, соответственно, символ &#8216;|&#8217; воспринимается как логическое &#8220;или&#8221;.. Таким образом, в var2 будет &#8220;o|n|e||t|w|o&#8221;&#8230;</p>
<p>Пусть такое поведение и является документированным, меня оно все равно расстраивает..</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/06/27/im-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
