LINUX.ORG.RU

Сообщения unterwulf

 

Чем легко переслать файл с одного хоста на другой в гетерогенной сети?

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

Например, если это *nix<->*nix и ни на одной стороне нет ни SSH ни NFS-сервера, то начинаются всякие извраты типа расшаривания каталога на отдающей стороне по HTTP каким-нибудь gatling-ом и скачивание его на получателе wget-ом.

Если *nix<->Windows, то мучительное вспоминание опций вызова smbclient-а и расшаривание каталога в Винде (если есть на это права). Если прав нет, то опять вариант с HTTP.

Если Windows<->*nix и каталог не расшарить, то совсем всё плохо. Даже при наличии SSH-сервера на приёмнике, использование psftp не сахар.

Иногда выручает имеющийся в сети файловый сервер.

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

Если один из хостов работает под Андроидом, то дело вообще табак (флешку некуда сувать).

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

Хочется от непривилегированного пользователя на одном хосте дать команду «готов принять», а на другом — «кинуть этот файл тому хосту». Без СМС, регистрации, аутентификации, и зависимости от конкретной сети.

Лоровец, поделись своим опытом в этом вопросе и отговори меня от запиливания своего велосипеда (уже поздно).

 , , , ,

unterwulf ()

Обрабатывать stdin в sh кусками

В соседнем треде идёт речь о написании генератора торрент-файлов и в связи с этим мне стало любопытно насколько просто будет написать его на шелле. У меня уже есть реализация Bencode на awk, поэтому вопрос только за подсчётом контрольных сумм блоков.

Крупными мазками вырисовывается что-то такое.

cat file1 file2 file3 | ( PIECELENGTH=262144; sz=$PIECELENGTH; while [ $sz = $PIECELENGTH ]; do head -c $PIECELENGTH | tee /tmp/piece.$$ | sha1sum; sz=$(stat -c%s /tmp/piece.$$); done )

Здесь раздражает временный файл и вызов stat. Приглашаю подумать, как обойтись без них. Python/Perl запрещены условием (иначе не интересно).

 ,

unterwulf ()

Не все даты одинаково хороши (для GNU софта)

Думал, баг нашёл, но, похоже, опять опыт :-)

Причину, вроде, осознал и готов признать это фичей, а не багом. Но задачка изначально была из разряда со звёздочкой (recfix из состава recutils не валидировал файл, содержащий поле с датой 1984-04-01).

Кому интересно пораскинуть мозгами, вот простенький показательный и слишком очевидный пример, к которому всё свелось.

$ TZ=Europe/Moscow date -d "31 Mar 1984"
Сб. марта 31 00:00:00 MSK 1984
$ TZ=Europe/Moscow date -d "1 Apr 1984"
date: invalid date ‘1 Apr 1984’
$ TZ=Europe/Moscow date -d "2 Apr 1984"
Пн. апр.  2 00:00:00 MSD 1984

Вроде бы и логично всё, но если не сталкиваться с таким (а столкнуться статистически довольно сложно), можно отхватить.

Например, человек, родившийся в этот день, сообщает, что, вроде бы у него был случай, когда некий сайт, требующий указать дату рождения, никак не хотел принимать таковую.

 , , ,

unterwulf ()

Условная выдача в зависимости от HTTP-заголовка Accept в запросе

Адресую свой вопрос администраторам веб-серверов.

Имеет ли какой-то из мэйнстримовых веб-серверов настройки, позволяющие выдавать различные статичные файлы при запросе одного и того же URL с разными значениями заголовка Accept.

Например, если запрос был:

GET /dir/ HTTP/1.1
Accept: text/html
то выдать /dir/index.html, а если
GET /dir/ HTTP/1.1
Accept: text/plain
то /dir/index.txt.

Т.е. нужны условные индексы.

Также нужно выдавать сообщения об ошибках HTTP в запрошенном формате, вместо безусловного HTML.

Ну, и совсем шиком было бы ещё и уметь выдать файл в запрошенной кодировке. Например, если запрос был:

GET /dir/file.txt HTTP/1.1
Accept: text/plain;charset=cp866
то выдать /dir/file.cp866.txt, а если
GET /dir/file.txt HTTP/1.1
Accept: text/plain;charset=UTF-8
то выдать /dir/file.UTF-8.txt.

Т.е. уметь делать внутренний rewrite в зависимости от Accept.

Если ещё и с перебором всех значений в Accept с учётом их веса вообще бы бомба была.

Понятно, что эти заботы можно переложить на любой скриптовый язык. Вопрос мой в том, поддерживает ли какой-то веб-сервер подобное своими средствами.

Спасибо.

 ,

unterwulf ()

Ссылка на необновляемый репозиторий на repo.or.cz на главной странице проекта

На главной странице http://www.midnight-commander.org сообщается, что:

We also have an autosyncing Git mirror at ​repo.or.cz. It uses gitweb as the web-interface to Git and can therefore provide some information normally unavailable via Trac Git browser plug-in:

git clone git://repo.or.cz/midnight-commander.git
git clone http://repo.or.cz/r/midnight-commander.git (for those who are behind a firewall)

Последние коммиты в том репозитории аж от 2013 года.

За историей MC не слежу, но, судя по тексту, этот зеркальный репозиторий был нужен только из-за его веб-интерфейса. Видимо, с тех пор основной репозиторий переехал на GitHub и нужда в отдельном репозитории с веб-интерфейсом отпала.

Предлагаю удалить ссылку на репозиторий repo.or.cz с главной, чтоб не вводить общественность в заблуждение.

Без задней мысли я склонировал себе MC именно с repo.or.cz, сделал и заслал патч относительно его, а потом только случайно увидел, что предыдущий коммит-то из 2013-го :)

 , ,

unterwulf ()

Чтение значения переменной из файла в shell-скрипте

Из серии «я познаю мир».

Ковыряясь в инит-скриптах замшелого Линукса, установленного на моём NAS, встретил следующую строку

read line <"$pid_file"

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

line=$(cat "$pid_file")

выглядит куда нагляднее (не то, что башизм $(<"$pid_file")). Но, приведя пульс в порядок и отогнав приступ праведного гнева, я стал размышлять над этой строчкой:

  • не порождаются суб-шелл и cat (минус два форка)
  • читается почти как well-written prose (если не считать косяк в виде имени line для переменной, содержащей pid)
  • надо брать на вооружение

Беглый анализ показывает, что в современном Дебиане оба подхода примерно одинаково популярны:

$ grep '=$(cat [^)]*)' -r /etc/ 2>/dev/null | wc -l
10
$ egrep 'read [[:alpha:]_][[:alnum:]_]*[[:blank:]]*<' -r /etc/ 2>/dev/null | wc -l
7

Что скажут ценители?

Ну, и для развлечения тест производительности :-)

Классика:

$ cat cat_test.sh
#!/bin/sh

i=0

while [ $i -lt $1 ]; do
    var=$(cat value)
    i=$(($i+1))
done

echo $var

Башизм:

$ cat bashcat_test.sh 
#!/bin/bash

i=0

while [ $i -lt $1 ]; do
    var=$(< value)
    i=$(($i+1))
done

echo $var

read:

$ cat read_test.sh
#!/bin/sh

i=0

while [ $i -lt $1 ]; do
    read var < value
    i=$(($i+1))
done

echo $var

Результаты:

$ echo this is a value > value
$ time ./cat_test.sh 1000
this is a value

real    0m2.129s
user    0m0.056s
sys     0m0.212s
$ time ./bashcat_test.sh 1000
this is a value

real    0m0.777s
user    0m0.108s
sys     0m0.144s

$ time ./read_test.sh 1000
this is a value

real    0m0.036s
user    0m0.000s
sys     0m0.036s

 , , , ,

unterwulf ()

Pascal case (он же upper camel case) в plain C

Прошу накидать названия проектов, которые используют PascalCase для именования пользовательских типов в коде на plain C. Мне кроме Pidgin и примеров из книги Кернигана и Пайка «Практика программирования» ничего найти с ходу не удалось.

Буду также благодарен за ссылки на дельные тезисы почему в Си традиционно не используется смешанный регистр.

Тема стара как Си, но почему-то большинство опенсорс проектов всё ещё предпочитают _t, зная, что он зарезервирован POSIX.

N.B. Вариант struct name_of_type (без использования typedef) не предлагать.

 

unterwulf ()

EnerGenie EG-PMS-LAN и egctl

Недавно стал обладателем сабжевой железки [1]. Это управляемый по Ethernet сетевой фильтр. Поддержка Linux со стороны производителя отсутствует. В Сети нашёл только скрипт, который при помощи curl управляет устройством через веб-интерфейс [2].

Собирался пользоваться этим скриптом, но на сайте производителя обнаружил документ [3] с описанием нехитрого протокола, используемого устройством, и тут же написал утилитку реализующую его.

Оставляю ссылку на неё здесь, на случай если кто-то на ЛОРе тоже пользуется данным устройством или задумывается о его приобретении.

Исходники на ГитХабе: https://github.com/unterwulf/egctl

[1] http://www.ixbt.com/power/ups/eg-pms-lan.shtml
[2] http://rewoo.wordpress.com/2012/07/27/lampengeist-15/
[3] http://www.energenie.com/Repository/6668/EG-PMS-LAN_driver_90F124ED-5B9A-45FA...

 , ,

unterwulf ()

Замена е на ё и обратно из нормального режима Vim

Осознал необходимость быстрой замены е на ё и обратно из нормального режима Vim, чего-то наподобие команды ~. Наборосал такую функцию.

function AltIo()
  let l:repl = { "е": "ё", "ё": "е", "Е": "Ё", "Ё": "Е" }
  normal x
  if (has_key(l:repl, @"))
    execute "normal i" . l:repl[@"]
  else
    normal u
  endif
endfunction

com AltIo call AltIo()

nmap <Tab> :AltIo^M

Она работает как надо, но хочется лучшего. Как минимум, чтобы не было лишних дёрганий x и u, когда под курсором находится и не е и не ё.

Сам, конечно, разберусь, но так хочется почувствовать поддержку ЛОРа и послушать язвительные комментарии знатоков vimscript.

 ,

unterwulf ()

ipsec в OpenBSD

Вопрос к знатокам OpenBSD. Настраиваю ipsec через файл /etc/ipsec.conf. После этого запускаю isakmpd -K и загружаю в него настройки ipsecctl -f /etc/ipsec.conf. isakmpd инициирует соедиение с удалённой стороной и поднимает ipsec-туннель.

Вопросы:

  • Каким спобом кроме перезапуска isakmpd можно опускать/поднимать туннель? (Единственное что приходит на ум: ipsecctl -F ; ipsecctl -f /etc/ipsec.conf не приводит к желанному результату.)
  • Если удалённая сторона удаляет туннель, должен ли он снова подняться по запросу (как это происходит в openswan под Linux)? Иными словами туннель лежит, я запускаю ping и ожидаю, что isakmpd поймёт, что есть трафик для пира, с которым ещё не согласованы SA и начнёт процедуру согласования, но этого не происходит. Вопрос — оно в OpenBSD вообще должно так работать?

Толковые ссылки по теме приветствуются.

 , ,

unterwulf ()

МТС и его ДНС

Второго дня приехал в отпуск на дачу с уверенностью, что буду без проблем пользоваться мобильным интернетом от МТС (опция БИТ), но не тут-то было. Обнаружились дикие тормоза при обращении к DNS.

tcpdump показал, что МТСовские сервера имён часто отвечают друг за дружку. Например при попытке пинговать ЛОР, я вижу:

12:15:41.682243 IP 172.24.35.31.33230 > 217.66.145.1.53: 32676+ A? linux.org.ru. (30)
12:15:42.560503 IP 217.66.145.2.53 > 172.24.35.31.33230: 32676 1/3/0 A 217.76.32.61 (116)
12:15:42.560544 IP 172.24.35.31 > 217.66.145.2: ICMP 172.24.35.31 udp port 33230 unreachable, length 152
12:15:46.682544 IP 172.24.35.31.45651 > 217.66.145.2.53: 32676+ A? linux.org.ru. (30)
12:15:46.684220 IP 172.24.35.31.34809 > 217.66.145.1.53: 28245+ A? linux.org.ru. (30)
12:15:47.598504 IP 217.66.145.1.53 > 172.24.35.31.45651: 32676 1/2/2 A 217.76.32.61 (126)
12:15:47.598547 IP 172.24.35.31 > 217.66.145.1: ICMP 172.24.35.31 udp port 45651 unreachable, length 162

Это выглядит так, что мы спросили 217.66.145.1, нам ответил 217.66.145.2, а мы его послали, т.к. ждём ответа от 217.66.145.1.

Ступор случается, видимо, до тех пор, пока не ответит тот сервер, которого спросили. (При каких обстоятельствах это случается выяснить не удаётся.)

Более того, если попросить неМТСовский сервер имён помочь нам, случается страшное.

vs@trixter$ dig @8.8.8.8 linux.org.ru
;; reply from unexpected source: 217.66.145.2#53, expected 8.8.8.8#53
;; reply from unexpected source: 217.66.145.2#53, expected 8.8.8.8#53

; <<>> DiG 9.4.2 <<>> @8.8.8.8 linux.org.ru
; (1 server found)
;; global options:  printcmd
;; connection timed out; no servers could be reached

Tcpdump:

12:13:39.058508 IP 172.24.35.31.44733 > 8.8.8.8.53: 3548+ A? linux.org.ru. (30)
12:13:44.058557 IP 172.24.35.31.44733 > 8.8.8.8.53: 3548+ A? linux.org.ru. (30)
12:13:47.850503 IP 217.66.145.2.53 > 172.24.35.31.44733: 3548 1/2/2 A 217.76.32.61 (126)
12:13:49.059541 IP 172.24.35.31.44733 > 8.8.8.8.53: 3548+ A? linux.org.ru. (30)
12:13:52.019505 IP 217.66.145.2.53 > 172.24.35.31.44733: 3548 1/2/2 A 217.76.32.61 (126)
12:13:54.103505 IP 217.66.145.2.53 > 172.24.35.31.44733: 3548 1/2/2 A 217.76.32.61 (126)
12:13:54.103568 IP 172.24.35.31 > 217.66.145.2: ICMP 172.24.35.31 udp port 44733 unreachable, length 162

Т.е. МТС перехватил запросы к «чужим» серверам и стал сам на них отвечать от своего имени.

Сталкивался ли кто-то с подобным, и есть ли идеи, как это лечить?

Как легко предположить, nameserver 8.8.8.8 в /etc/resolv.conf не помогает, options timeout:n тоже не об этом.

Первое что приходит на ум, это оставить в /etc/resolv.conf только один namesever и попробовать обмануть локальный ресолвер, подменяя адрес второго МТСного сервера имён на адрес оставленного при помощи iptables. Но это очень коряво, да и iptables у меня на ноуте не используются. Может есть какая-то секретная настройка, позволяющая дефолтовому ресолверу принимать ответы от любого сервера из /etc/resolv.conf, не взирая на то, какому он отправил запрос?

Некоторые детали:

  • Подключение происходит через сотовый телефон по Bluetooth.
  • С соединением всё в порядке, кроме ДНС.
  • Все сетевые настройки получаются по DHCP:
    vs@trixter$ cat /etc/resolv.conf
    # Generated by dhcpcd from ppp0
    # /etc/resolv.conf.head can replace this line
    nameserver 217.66.145.1
    nameserver 217.66.145.2
    # /etc/resolv.conf.tail can replace this line
    vs@trixter$ ifconfig ppp0
    ppp0      Link encap:Point-to-Point Protocol
              inet addr:172.24.35.31  P-t-P:10.64.64.64  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
              RX packets:3396 errors:0 dropped:0 overruns:0 frame:0
              TX packets:4360 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:3
              RX bytes:2196162 (2.0 Mb)  TX bytes:797231 (778.5 Kb)
    
  • Ещё немного цирка
    vs@trixter$ dig linux.org.ru
    ;; reply from unexpected source: 217.66.145.2#53, expected 217.66.145.1#53
    ;; reply from unexpected source: 217.66.145.1#53, expected 217.66.145.2#53
    ;; reply from unexpected source: 217.66.145.2#53, expected 217.66.145.1#53
    ;; reply from unexpected source: 217.66.145.1#53, expected 217.66.145.2#53
    
    ; <<>> DiG 9.4.2 <<>> linux.org.ru
    ;; global options:  printcmd
    ;; connection timed out; no servers could be reached
    

    Tcpdump:

    12:08:20.026339 IP 172.24.35.31.54129 > 217.66.145.1.53: 53999+ A? linux.org.ru. (30)
    12:08:21.026602 IP 172.24.35.31.59808 > 217.66.145.2.53: 53999+ A? linux.org.ru. (30)
    12:08:21.207500 IP 217.66.145.1.53 > 172.24.35.31.54129: 53999 1/2/2 A 217.76.32.61 (126)
    12:08:21.406503 IP 217.66.145.1.53 > 172.24.35.31.59808: 53999 1/2/2 A 217.76.32.61 (126)
    12:08:21.406545 IP 172.24.35.31 > 217.66.145.1: ICMP 172.24.35.31 udp port 59808 unreachable, length 162
    

 , , ,

unterwulf ()

Замена cuetag на одном только шелле

Время от времени мне приходится разрезать скачанные образы музыкальных дисков в формате ape/cue или flac/cue. Проблема в том, что подобная нужда возникает довольно редко и система бывает уже переустановлена с последнего раза, а порта cuetools для моего дистрибутива нет, а апстим у этого пакета, похоже, дохлый и в непатченном виде, он уже не вполне работоспособен.

В общем, долго я это терпел, но таки не удержался и решил написать свой скрипт, которому не нужен был бы сишный cueprint и который бы работал сам по себе. К тому же, думал я, cue sheet — это простой текстовый формат, сам бог велел парсить его скриптами.

Сначала я попробовал использовать awk, но возня с обработкой значений в кавычках на нём выглядела уныло. Вторым пунктом я попробовал python, тут код выходил красивее, но на полпути меня настигло озарение — ведь cue sheet это, по сути, скрипт с командами в формате пригодном для передачи шеллу как есть.

Окрылённый этой мыслью я тут же принялся за написание скрипта на шелле. Время шло, но мне всё никак не удавалось заставить шелл парсить команды с учётом аргументов в двойных кавычках (чтобы TITLE «Two words» был интерпретирован как два аргумента, а не три).

После долгих проб, утомительного чтения стандарта POSIX и stackoverflow.com другого варианта кроме использования eval мне найти не удалось. А это значило, что красивой идее не суждено было быть воплощённой, т.к. использование eval неминуемо вызывало проблемы с безопасностью (TITLE «Two words» ; rm -rf ~), а фильтрация всех опасных конструкций превратила бы код в столь же унылое зрелище, как и вариант на awk.

Отчаявшийся, подавленный я всё же добил этот скрипт на шелле найдя лишь небольшое утешение в том, чтобы сделать его как можно более изящным и лаконичным.

Конечный вариант я и предлагаю широкой общественности ЛОРа. Вот его отличия от cuetag:

  • не имеет зависимости от cueprint (читай, не требует компиляции)
  • позволяет использовать свои «драйверы» для установки тегов (например, можно не только metaflac вызвать, но и сразу переименовать файлы в соответствии со значениями тегов)
  • в угоду простоте не проверяет валидность cue sheet-ов (хоть я и не смотрел проверяет ли cueprint, но свято верю в это), т.е. можно подстроить такой cue sheet, который будет интерпретирован неправильно, но это не страшно, т.к. максимум может привести только к неверным значениям тегов
  • состоит всего из 40 строк, 9 из которых комментарии или разделители

Просьба ценителям изящного шелл-скриптинга на чём свет высказывать свои критические замечания по коду.

Смореть в браузере: https://github.com/unterwulf/cuecmd
Тарбол: https://github.com/downloads/unterwulf/cuecmd/cuecmd-0.0.1.tar.gz

Спасибо за внимание.

p.s. Чтоб два раза не вставать, хочу порекламировать ещё один [не мой] скрипт, недавно попавшийся мне на просторах Интернета. Он позволяет удобно переименовывать файлы в любимом текстовом редакторе. Называется virn. Прост как три копейки. Его адрес https://github.com/jkramer/virn. Незаменим при ковырянии с музыкальными коллекциями.

 , , , ,

unterwulf ()

RSS подписка на новые темы