глаз

Administrativia

Перенёс бложик на dreamwidth. Не то, чтобы я буду туда писать, правда. Но вы там можете меня пофрендяшить! Access lists, я так понимаю, туда тоже проимпортировались.

Если будет возможность сделать редирект — грохну тут всё, хоть оно и противоречит принципу поддержания ссылочной связности интернета.

PS. Ох и пиздец же интерфейс ЖЖ стал, спустя 6 лет. DW в этом плане даёт сто очков вперёд.
глаз

Metro.people

Вот эта девочка зачем-то фотографировала меня в метро. Всё бы ничего, но со вспышкой. На телефон (какую-то нокию N-серии). Сиречь, светодиод этот светил с секунду.
глаз

[wiki] Список внешних ресурсов с учебными материалами

Что-то я подумал, что сайтов с заботливо структурированными учебными материалами куча, а в итоге никто ничего не знает, что где. Раньше был фдс-нет, где те же ссылки были, но теперь его нет. Посему, пусть у меня полежит, коли кто-то на порносайтик да заходит.

Собственно, сабж. Писал по памяти, так что много чего нет (забылось с годами). Если кто ещё что помнит — дополняйте.

Да, ешё практически перед самой смертью на фдс-нете выкладывалась подборка ботвы. Если кому надо, могу её захостить, только дайте, откуда её скачать.
глаз

[bourne shell] Построчное чтение, перенаправление и грабли

Вероятно, многие знают, что при помощи shell built-in read можно построчно читать всякое; особенно это актуально при считывании списка файлов, которые потенциально могут содержать пробелы (например, в выдаче ls или find) или чего-то подобного. Обычно это делается так:

Построчное чтение из файла:
while read line
do
  # code
done < file

Построчное чтение результата выполнения команды (вариант с перенаправлением):
ls | while read line
do
  # code
done

Вроде бы всё хорошо. Проблемы могут начаться в случае, когда во время чтения нужно изменять значения переменных. А именно, последний (и, кстати, наиболее часто используемый в случае, когда нужно обработать вывод команды, а не читать из файла) вариант приводит к созданию дочернего процесса (pipe же!), что приводит к тому, что все изменения переменных внутри тела цикла выполняются в подпроцессе и, как следствие, на процессе, в котором выполняется скрипт, не попадают. Это можно легко увидеть на следующем примере:
i=0; seq 1 3| while read line; do i=$(( $i + 1 )); done; echo $i
В bash и dash в результате будет выдан 0, в zsh и ksh (которые исполняют последний элемент пайплайна в текущем процессе в случае, если это shell built-in) — 3.
Обойти эту проблему можно несколькими способами. Один из них — использовать heredoc:
while read a b
do
  i=$(( $i + 1 ))
done <<EOF
`seq 1 3 | sed 's/^/1 /'`
EOF
echo $i
При этом, как можно видеть из примера выше, можно использовать произвольный пайплайн.
Очевидный недостаток этого решения — прежде, чем результат выполнения будет передан в цикл, он полностью будет получен. Это можно попытаться обойти, например, путём создания временного FIFO-файла:
fifofile=`mktemp`
rm "$fifofile"
mkfifo "$fifofile"

ls | sed 's/^/1 /' > "$fifofile" & # random command which output we need to parse
while read a b
do
  i=$(( $i + 1 ))
done < "$fifofile"
echo $i

rm "$fifofile"
Очевидно, что в данном случае строчка rm "$fifofile" будет выполнена после завершения цикла, что, по идее (так как read ждёт закрытия потока ввода), произойдёт только после завершения процесса, пишущего в FIFO и считывания из него всех данных.
Но всё же ощущается неаккуратность в виде наличия временных файлов. Тем более, что упражнение вида mktemp—rm—mkfifo теоретически может породить рейс. Можно попробовать соорудить конструкцию с созданием дескрипторов (like, exec 3<&0>&1):
exec 3<&0>&1

ls | sed 's/^/1 /' >&3 & # random command which output we need to parse
while read -u 3 a b
do
  i=$(( $i + 1 ))
done
echo $i

exec 3<&->&-

И, казалось бы, счастье есть: мы можем запихать произвольный пайплайн из процессов в этот дескриптор, а потом читать из него (или с помощью специального ключика у read, как в примере выше, или же просто <&3. Осталась одна маленькая проблема: если попытаться прибить скрипт до окончания его работы, то это ему ничуть не помешает. Посему, нужно повесить trap, который убивает дочерний процесс и завершает работу:
trap 'kill -9 $cpid; exit' TERM INT

exec 3<&0>&1

ls | sed 's/^/1 /' >&3 & # random command which output we need to parse
cpid=$!
while read -u 3 a b
do
  i=$(( $i + 1 ))
done
echo $i

exec 3<&->&-

Более аккуратного варианта как-то в голову не пришло. Если кто знает — поделитесь.

UPD. Таки приведённый вариант с дескрипторами работает только в zsh (не в dash). Буду думать, как его таки заимплементить.
глаз

Вышел MoinMoin 1.9.2


Появилась новая версия кросс-платформенного вики-сервера, написанного на языке Python — MoinMoin 1.9.2. В данной версии исправлен ряд серьёзных проблем с безопасностью, потенциально существовавших и в более старых ветках (начиная с 1.5). Разработчиками настоятельно рекомендуется обновиться до данной версии (или до версии 1.8.7, если обновление до ветки 1.9 невозможно или нежелательно по тем или иным причинам).

Ссылки:
глаз

(no subject)

Что-то я смотрю на этот ваш формспринг и не понимаю, зачем он нужен. Что позволяет делать — понимаю, нафига — нет.