<?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; SHELL</title>
	<atom:link href="http://alexey.sveshnikov.ru/blog/tag/shell/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>Магия в zsh</title>
		<link>http://alexey.sveshnikov.ru/blog/2008/11/04/zsh-magi/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2008/11/04/zsh-magi/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 22:02:47 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[magic]]></category>
		<category><![CDATA[zsh]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=88</guid>
		<description><![CDATA[Захотелось мне в этот чудесный выходной понедельник поагитировать за свой любимый шелл. Чем, кстати, вообще может похвастаться какой-либо шелл, имея в конкурентах такого монстра, как bash? Ведь в bash есть все, что может только пожелать обычный пользователь. А, собственно, и нечем. Поэтому разработчикам zsh пришлось пойти на хитрость и добавить в свое детище некоторое количество [...]]]></description>
			<content:encoded><![CDATA[<p>Захотелось мне в этот чудесный выходной понедельник поагитировать за свой любимый шелл. Чем, кстати, вообще может похвастаться какой-либо шелл, имея в конкурентах такого монстра, как bash? Ведь в bash есть все, что может только пожелать обычный пользователь. А, собственно, и нечем. Поэтому разработчикам zsh пришлось пойти на хитрость и добавить в свое детище некоторое количество магии :)</p>
<p>Большая ее порция досталась подсистеме автодополнения. Вот таким можно сделать дополнение имен файлов:<br />
<img src="http://alexey.sveshnikov.ru/blog/wp-content/uploads/2008/11/zsh-menu-completion.png" alt="zsh menu completion" title="zsh menu completion" width="500" height="132" class="aligncenter size-full wp-image-91" /><br />
(выбрать нужный вариант можно табом по старинке, курсорными клавишами или стандартными emacs-хоткеями)</p>
<p>А вот так &#8211; дополнение опций:<br />
<img src="http://alexey.sveshnikov.ru/blog/wp-content/uploads/2008/11/zsh-menu-completion-opts.png" alt="" title="zsh-menu-completion-opts" width="500" height="197" class="aligncenter size-full wp-image-99" /></p>
<p>Еще одна моя любимая магическая штуковина в автодополнении выглядит так: допустим, нужно подправить файл /usr/local/etc/rc.d/mysql. Пользователь bash бы ввел такую команду:<br />
<code>vim /usr/l[TAB]/e[TAB]/r[TAB]/m[TAB]</code><br />
В zsh все несколько проще, а именно:<br />
<code>vim /u/l/e/r/m[TAB]</code><br />
После нажатия [TAB] все элементы пути будут дополнены. Если вариантов несколько, можно будет вручную выбрать нужный.</p>
<p>Ну вот, я вам передал примерно 0.65 процента магии zsh. Помимо автодополнения, ее залежи находятся в подсистеме подстановок (man zshexpn), но там я сам не очень уверенно ориентируюсь. Все-таки одна из прелестей zsh заключается в том, что мне необязательно учиться им пользоваться &#8211; для начала можно ограничиться только bash-совместимым подмножеством функций, регулярно натыкаясь на приятные мелочи в реализации привычных вещей.</p>
<p>Дальнейшее чтение:<br />
<a href="http://citkit.ru/articles/1083/">обзор zsh</a> от Алексея Федорчука,<br />
Собрание хаков и идиом zsh: <a href="http://grml.org/zsh/zsh-lovers.html">zsh lovers</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2008/11/04/zsh-magi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SSH для бэкапов и мониторинга: ограничиваем доступ.</title>
		<link>http://alexey.sveshnikov.ru/blog/2008/03/04/restricted-ssh/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2008/03/04/restricted-ssh/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 23:12:57 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/2008/03/04/restricted-ssh/</guid>
		<description><![CDATA[&#8220;Бэкап &#8211; акт проявления трусости&#8221; (c) народная мудрость Я труслив :) Во-первых, я делаю бэкапы. Во-вторых, я их боюсь передать без шифрования и, в третьих, иногда и храню их зашифрованными. Как правильно организовать передачу бэкапов с одного сервера на другой? Дампы этого блога у меня передаются по http. Они зашифрованны, да и особо ценных данных [...]]]></description>
			<content:encoded><![CDATA[<div style="text-align: right;"><i>&#8220;Бэкап &#8211; акт проявления трусости&#8221; (c) народная мудрость</i></div>
<p>Я труслив :) Во-первых, я делаю бэкапы. Во-вторых, я их боюсь передать без шифрования и, в третьих, иногда и храню их зашифрованными.</p>
<p>Как правильно организовать передачу бэкапов с одного сервера на другой? Дампы этого блога у меня передаются по http. Они зашифрованны, да и особо ценных данных здесь нет, поэтому http меня не смущает. А как поступить с данными по-важнее? Конечно, ssh. А как при этом запретить пользователю выполнять какие-либо действия, кроме как копирования к себе бэкапа? Представим себе, что бэкап-сервер находится во вражеском дата-центре или просто вы не можете проконтролировать к нему доступ (в т.ч. физический). Нас выручит опция command файла authorized_keys.</p>
<p>Например, если необходимо предоставить доступ только к файлу backup.tgz, то в authorized_keys в самом начале соответствующей строки можно дописать следующее &#8220;command=&#8217;cat backup.tgz&#8217;&#8221;. Теперь при каждом коннекте будет автоматически выполняться команда cat backup.tgz, вам остается только перенаправить вывод в файл. Если дампов несколько, то можно написать небольшой скриптик вида:<code>#!/bin/sh<br />
read file<br />
case "$file" in<br />
"foo") cat foo.tgz ;;<br />
"bar") cat bar.tgz ;;<br />
esac</code> И прописать его в качестве команды по умолчанию. Да, не лишним было бы добавить опции no-port-forwarding, no-pty и все прочие no-*</p>
<p>Теперь копировать файл с удаленной машины можно вот такой командой:<code>echo "foo" | ssh backup@server > foo-`date +%Y-%m-%d`.tgz</code></p>
<p>Кроме как для бэкапов, такое же решение может подойти и для мониторинга. Когда нагиос стучится на удаленный сервер, чтобы собрать какую-либо статистику, полный ssh-доступ ему не нужен.</p>
<p>По-моему, все, что я описал примитивно по сложности и вместе с тем весьма надежно. Так может быть прекратим без надобности дописывать authorized_keys на серверах? Одна запись для себя, любимого, одна для бэкапов, одна для мониторинга.. ой, еще каких-то две..  дальше продолжать? :)</p>
<p>Кстати, а есть ли способы более тонко настраивать уровень доступа к ssh?</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2008/03/04/restricted-ssh/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>О прозрачности в командной строке [pv]</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/12/04/%d0%be-%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b0%d1%87%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d0%b2-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d0%bd%d0%be%d0%b9-%d1%81%d1%82%d1%80%d0%be%d0%ba%d0%b5-pv/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/12/04/%d0%be-%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b0%d1%87%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d0%b2-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d0%bd%d0%be%d0%b9-%d1%81%d1%82%d1%80%d0%be%d0%ba%d0%b5-pv/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 21:01:55 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[pv]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/2007/12/04/%d0%be-%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b0%d1%87%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d0%b2-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d0%bd%d0%be%d0%b9-%d1%81%d1%82%d1%80%d0%be%d0%ba%d0%b5-pv/</guid>
		<description><![CDATA[Эта запись будет посвящена программе с лаконичным названием pv. А слово &#8220;прозрачность&#8221; пусть не ассоциируется у вас с пресловутыми compiz-fusion, тут все гораздо интереснее :) Итак, чем плох избитый пример c передачей файлов через netcat? Мне, например, не удобно то, что нет возможности наблюдать за процессом. В самом деле, возможности юниксовых шеллов в этом плане [...]]]></description>
			<content:encoded><![CDATA[<p>Эта запись будет посвящена программе с лаконичным названием pv. А слово &#8220;прозрачность&#8221; пусть не ассоциируется у вас с пресловутыми compiz-fusion, тут все гораздо интереснее :)</p>
<p>Итак, чем плох избитый пример c передачей файлов через netcat? Мне, например, не удобно то, что нет возможности наблюдать за процессом. В самом деле, возможности юниксовых шеллов в этом плане довольно скромные: с помощью tee можно сохранить поток в файл, который потом наблюдать через tail или следить за его размером командой &#8216;watch ls&#8217;. Этого достаточно для отладки, но мало для комфортной работы. </p>
<p>Поэтому программа pv просто не могла не появиться. Все очень в духе UNIX &#8211; маленькая утилитка, которая пропускает через себя поток данных и в STDERR отправляет некоторую статистику по ним. Но _как_ она это делает! Покажу на примерах:</p>
<p>Всегда хотел узнать:<br />
<code>dainichi@fujitsu:~$ cat /dev/toilet_paper | pv >/dev/shreder<br />
1.01GB 0:00:02 [ 569MB/s] [  <=>                                                                      ]</code><br />
Ага, больше десяти рулонов в секунду.. </p>
<p>Прикинемся взрослой программой с выводом а-ля wget:<br />
<code>dainichi@fujitsu:~$ cat file | pv -s `stat -c %s file` | nc so.far.away 1234<br />
 236kB 0:00:05 [ 346КB/s] [==================>                                                             ] 72%</code></p>
<p>Ограничим скорость обработки файла, чтобы mplayer не тормозил:<br />
<code>dainichi@fujitsu:~$ cat big_log | pv -L 100к | log_processor > report</code></p>
<p>Пример из мана &#8211; архивирование каталога и одновременное отображение прогрессбара<br />
<code>  (tar cf - . | pv -n -s `du -sb . | awk '{print $1}'` \<br />
     | gzip -9 > out.tgz) 2>&#038;1 | dialog --gauge 'Progress' 7 70</code></p>
<p>И, напоследок, скриншот с <a href="http://www.ivarch.com/programs/pv.shtml">домашней страницы</a> проекта:<br />
<img src='http://alexey.sveshnikov.ru/blog/wp-content/uploads/2007/12/pv.png' alt='скриншот с домашней странички проекта pv' /></p>
<p>Здорово? :) По-моему, да :) </p>
<p>Кстати. а какие еще способы &#8220;очеловечить&#8221; интерфейс командной строки вы знаете?</p>
<p><b>UPD</b> <a href="http://libc6.blogspot.com/">Андрей Афанасенко</a> поделился ссылкой вот на такое <a href="http://www.theiling.de/projects/bar.html">чудо</a>:<br />
<img src='http://alexey.sveshnikov.ru/blog/wp-content/uploads/2007/12/bar-cat-n.gif' alt='' /><br />
Написана эта программа на bash и во многих случаях ее использовать гораздо удобнее, чем pv.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/12/04/%d0%be-%d0%bf%d1%80%d0%be%d0%b7%d1%80%d0%b0%d1%87%d0%bd%d0%be%d1%81%d1%82%d0%b8-%d0%b2-%d0%ba%d0%be%d0%bc%d0%b0%d0%bd%d0%b4%d0%bd%d0%be%d0%b9-%d1%81%d1%82%d1%80%d0%be%d0%ba%d0%b5-pv/feed/</wfw:commentRss>
		<slash:comments>4</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>HTTP сервер в одну строку: версия 2.0</title>
		<link>http://alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/#comments</comments>
		<pubDate>Wed, 29 Aug 2007 20:00:11 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[netcat]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/2007/08/30/http-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80-%d0%b2-%d0%be%d0%b4%d0%bd%d1%83-%d1%81%d1%82%d1%80%d0%be%d0%ba%d1%83-%d0%b2%d0%b5%d1%80%d1%81%d0%b8%d1%8f-20/</guid>
		<description><![CDATA[Идея с HTTP сервером на bash мне не дает покоя. Вернуться к ней меня побудила.. попытка воспользоваться старой версией: получалсь не очень :) Поэтому решил довести его до ума. Что-то дописал, что-то выкинул, полчилось следующее: :;while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;z=$r;while [ ${#z} -gt 2 ];do $r z;done;f=`$e [...]]]></description>
			<content:encoded><![CDATA[<p>Идея с <a href="http://alexey.sveshnikov.ru/blog/2006/12/23/http-сервер-размером-в-222-байта/">HTTP сервером на bash</a> мне не дает покоя.</p>
<p>Вернуться к ней меня побудила.. попытка воспользоваться старой версией: получалсь не  очень :)</p>
<p>Поэтому решил довести его до ума. Что-то дописал, что-то выкинул, полчилось следующее:<br />
<code>:;while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;z=$r;while [ ${#z} -gt 2 ];do $r z;done;f=`$e $b|sed 's/[^a-z0-9_.-]//gi'`;h="HTTP/1.0";o="$h 200 OK\r\n";c="Content";if [ -z $f ];then($e $o;ls|(while $r n;do if [ -f "$n" ]; then $e "&lt;a href=\"/$n\"&gt;`ls -gh $n`&lt;/a&gt;&lt;br&gt;";fi;done););elif [ -f $f ];then $e "$o$c-Type: `file -ib $f`\n$c-Length: `stat -c%s $f`";$e;cat $f;else $e -e "$h 404 Not Found\n\n404\n";fi)';done</code></p>
<p>Теперь по URL http://ваш_ip:8080/ можно получить доступ ко всем файлам, находящимся в текущим каталоге. Очевидных и прямолинейных способов сменить каталог нет. Как и раньше, протестировано и работает под Linux, bash 3.2.13, и с хоббитовским netcat v1.10 с поддержкой опции -с (запустите netcat -h и посмотрите. Как минимум в Ubuntu, Debian и Fedora Core такая опция есть).</p>
<p>Теперь строка занимает 434 байт,  что на 212 больше, чем прошлая версия. И мне кажется, что я с толком потратил эти байты: новый сервер обрабатывает ошибку 404, кроме того, теперь он работает без задержки, которая раньше требовалась для того, чтобы была возможность его остановить с помощью Ctrl-C. Для успешных запросов сервер отдает нормальные заголовки, с размером файла и даже с его MIME-типом. Например:</p>
<p><code>dainichi@fujitsu:~/backup$ echo "GET /6.1-RELEASE-i386-disc1.iso HTTP/1.1" | nc localhost 8080 | head -n3<br />
HTTP/1.x 200 OK<br />
Content-Type: application/x-iso9660<br />
Content-Length: 529784832</code></p>
<p>Для удобства можно сохранить его в файл и написать в .bash_profile примерно следующее:<code>alias share='sh ~/bash_httpd.sh'</code></p>
<p>Да, были попытки его еще уменьшить, но они не увенчались успехом. Есть такой вариант, но он даже больше:<br />
<code>w=while;d=done;e=echo;r=read;echo "true; $w [ @? -eq 0 ];do nc -vlp 8080 -c'($r a b c;f={$e @b|sed 's/[^a-z0-9_.-]//gi'{;h=}HTTP/1.x};o=}@h 200 OK#};c=}Content};if [ -z @f ];then($e @o;ls|(while $r n;do $e }<a href=\}/@n\}>@n</a><br />};done));elif [ -f @f ];then $e }@o@c-Type: {file -ib @f{#@c-Length: {stat -c%s @f{#};cat @f;else $e }@h 404 Not Found##404#};fi)';done"|tr "@{}#" '$`"<br />
'|sh</code> Оставил его, потому что выглядит страшно, детей пугать &#8211; самое то :)</p>
<p>Если у вас получится сэкономить еще пару байтов, то милости просим в комментаторскую :)</p>
<p><b>UPD: 03.09.2007:</b> Код обновлен, в него вошли <a href="http://sovety.blogspot.com/2007/08/21.html">исправления</a>, которые сделал тов. jetxee, за которые ему большое спасибо.</p>
<p><b>UPD: 03.09.2007:</b> Я удивлен тому факту, что эта заметка <a href="http://news2.ru/story/54417/"> попала в топ news2</a>, спасибо <a href="http://dikiy.com/blog/">dik&#8217;у</a> за то, что добавил ее. Я рад, что она многим показалась интересной.</p>
<p><b>UPD: 07.09.2007:</b> Товарищ Ed очень здорово прооптимизировал код. Вот, что у него вышло:<br />
<code>while :;do nc -p8080 -vnlc'r=read;e="echo -e";$r a b c;while [ -n "`$e $a|tr -d "\r\n"`" ];do $r a;done;f=`$e $b|sed s/.//`;h="HTTP/1.0";z="404 Not Found\n";[ -z $f ]&#038;&#038;(ls|while $r n;do [ -f $n ]&#038;&#038;$e "<a>$n</a>";done)||([ -f $f ]&#038;&#038;($e "$h 200 OK\r\nContent-Type: `file -ib $f`\n";cat $f)||$e "$h $z\n$z")';done</code></p>
<p>Работоспособность проверялась автором на таблетке Nokia N800, а у меня в Kubuntu 7.04 что-то не заработало. Сегодня вечером буду разбираться :)</p>
<p>p.s. Мне теперь стыдно из-за того, что сам не догадался использовать &#038;&#038; и || вместо if..then. :(</p>
<p>p.p.s. stay <a href="http://feeds.feedburner.com/Bookmarks-on-tranquilizers">tuned</a>!</p>
<p><b>UPD 18.08.2008:</b> О, <a href="http://habrahabr.ru/blogs/crazydev/37245/">написали</a> про это безобразие на Хабре, назвали меня извращенцем. Хулиганьё!! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/feed/</wfw:commentRss>
		<slash:comments>51</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>Hint [10]</title>
		<link>http://alexey.sveshnikov.ru/blog/2006/12/23/hint-10/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2006/12/23/hint-10/#comments</comments>
		<pubDate>Sat, 23 Dec 2006 14:14:32 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[UNIX]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[SHELL]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=18</guid>
		<description><![CDATA[[10] Все мы с пеленок знаем, что &#038; значит запустить программу в фоновом режиме, но лично у меня случаи, когда такая форма запуска является оправданной встречаются редко. Хотя недавно я &#8220;открыл для себя&#8221; один из классов таких случаев &#8211; какие-либо действия с сетью, которые сами по себе не ресурсоемки, но могут выполняться долго вследствие больших [...]]]></description>
			<content:encoded><![CDATA[<p>[10] Все мы с пеленок знаем, что &#038; значит запустить программу в фоновом режиме, но лично у меня случаи, когда такая форма запуска является оправданной встречаются редко. Хотя недавно я &#8220;открыл для себя&#8221; один из классов таких случаев &#8211; какие-либо действия с сетью, которые сами по себе не ресурсоемки, но могут выполняться долго вследствие больших таймаутов.</p>
<p>Вот так я проверяю список хвостов на &#8220;пингуемость&#8221;:</p>
<p>cat proxies | (IFS=&#8221;:\n&#8221;; while read ip port; do (if ping -w 1 -c 1 -q $ip>/dev/null; then echo &#8220;$ip:$port&#8221;; else echo &#8220;bad: $ip:$port&#8221;; fi)& done;) | tee proxies_pingable</p>
<p>В данном случае я запускаю в фоне сабшелл (if ping -w 1 -c 1 -q $ip>/dev/null; then echo &#8220;$ip:$port&#8221;; else echo &#8220;bad: $ip:$port&#8221;; fi), потому скрипт приступает к пингу следующего хоста, не дожидаясь, когда завершится проверка предыдущего. Выигрыш по времени пропорционален количеству хостов &#8211; если их 100, то практически стократный!<br />
Правда, нужно быть аккуратным &#8211; если в списке 10 тысяч хостов, то это будет уже больше похоже на DoS.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2006/12/23/hint-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP сервер размером в 222 байта :)</title>
		<link>http://alexey.sveshnikov.ru/blog/2006/12/23/http-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80%d0%be%d0%bc-%d0%b2-222-%d0%b1%d0%b0%d0%b9%d1%82%d0%b0/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2006/12/23/http-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80%d0%be%d0%bc-%d0%b2-222-%d0%b1%d0%b0%d0%b9%d1%82%d0%b0/#comments</comments>
		<pubDate>Sat, 23 Dec 2006 01:30:39 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[SHELL]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[netcat]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=17</guid>
		<description><![CDATA[В продолжение предыдущей идеи с передачей файлов по HTTP. Я не удержался и написал вполне полноценный (для нужд раздачи файлов на соседний компьютер) HTTP сервер: while true; do nc -vv -l -p 8080 -c '( read a b c; file=`echo $b &#124; sed 's/[^a-z0-9.]//g'`; if [ a$file = "a" ]; then ( ls &#124; (while [...]]]></description>
			<content:encoded><![CDATA[<p>В продолжение <a href="http://alexey.sveshnikov.ru/blog/2006/12/22/hint-9-swiss-army-knife/">предыдущей идеи</a> с передачей файлов по HTTP. Я не удержался и написал вполне полноценный (для нужд раздачи файлов на соседний компьютер) HTTP сервер:</p>
<p><code>while true; do nc -vv -l -p 8080 -c '( read a b c; file=`echo $b | sed 's/[^a-z0-9.]//g'`; if [ a$file = "a" ]; then ( ls | (while read f; do echo "<a href=$f>$f</a><br />"; done) ); else cat $PWD/$file; fi )'; sleep 1; done</code></p>
<p>(все это &#8211; одна команда, должна вводиться в одну строку. Тестировалось в linux/bash 3.1.17)</p>
<p>Вот и все :) Правда, на этот раз я опять решил отказаться от заголовков ответа, т.к. это слишком усложнит &#8220;команду&#8221;, но при желании их можно взять из <a href="http://alexey.sveshnikov.ru/blog/2006/12/22/hint-9-swiss-army-knife/">предыдущего</a> примера. Этот сервер отдает все файлы, которые есть в текущем каталоге и пытается противодействовать попыткам его сменить. В случае, если запрашивается корневая директория, то управление передается своеобразному mod_index &#8211; т.е. выводится список файлов-ссылок. В конце добавлена задержка в 1 сек для того, чтобы была возможность убить его нажатием Ctrl-C.</p>
<p>Воистину, netcat одна из моих любимых программ!</p>
<p>p.s. Кто теперь осмелится заявить, что я не извращенец? :))</p>
<p><b>UPD: немного доделал его, см <a href="http://alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/">новую версию</a></b></p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2006/12/23/http-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80%d0%be%d0%bc-%d0%b2-222-%d0%b1%d0%b0%d0%b9%d1%82%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ssh и анонимность</title>
		<link>http://alexey.sveshnikov.ru/blog/2006/08/08/ssh-%d0%b8-%d0%b0%d0%bd%d0%be%d0%bd%d0%b8%d0%bc%d0%bd%d0%be%d1%81%d1%82%d1%8c/</link>
		<comments>http://alexey.sveshnikov.ru/blog/2006/08/08/ssh-%d0%b8-%d0%b0%d0%bd%d0%be%d0%bd%d0%b8%d0%bc%d0%bd%d0%be%d1%81%d1%82%d1%8c/#comments</comments>
		<pubDate>Tue, 08 Aug 2006 13:59:22 +0000</pubDate>
		<dc:creator>Alexey Sveshnikov</dc:creator>
				<category><![CDATA[UNIX]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SHELL]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://alexey.sveshnikov.ru/blog/?p=6</guid>
		<description><![CDATA[Сегодня обнаружил, что текстовое поле в конце файла id_rsa.pub &#8211; просто комментарий. Это значит, что после копирования его на удаленный хост в authorized_keys можно заменить свой настоящий логин и имя хоста на строку &#8220;тут был Вася&#8221; и никто никогда не поймет, кто такой Вася и как он сюда попал. И еще. Можно работать на удаленном [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня обнаружил, что текстовое поле в конце файла id_rsa.pub &#8211; просто комментарий. Это значит, что после копирования его на удаленный хост в authorized_keys можно заменить свой настоящий логин и имя хоста на строку &#8220;тут был Вася&#8221; и никто никогда не поймет, кто такой Вася и как он сюда попал.<br />
И еще. Можно работать на удаленном хосте, не светясь ни в auth.log, ни в `who` ни в `last`, без возможности посмотреть, что творится в консоли через watch &#8211; для этого достаточно запускать ssh-сессию так: ssh user@host &#8220;bash&#8221;.</p>
<p>Мораль здесь одна: если у человека есть ssh аккаунт на машине, то контроллировать его действия практически невозможно.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexey.sveshnikov.ru/blog/2006/08/08/ssh-%d0%b8-%d0%b0%d0%bd%d0%be%d0%bd%d0%b8%d0%bc%d0%bd%d0%be%d1%81%d1%82%d1%8c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
