Tag Archives: linux - Page 2

Німецьке QWERTY

Німці використовують деякі букви, яких нема в стандартній латинській розкладці: ÄÖÜẞ, тому існує окрема німецька розкладка. Але біда, біда, вона не QWERTY, а QWERTZ, і Z та Y поміняні місцями. Правильної розкладки чомусь нема, тому я вирішив зробити свою. Має працювати на всіх системах що використовують X keyboard extension з X Window System.

Замість кнопки “-” отримуємо “ß”, замість “[” – “Ü”, “;” – “Ö” ну а замість “‘” – “Ä”. Всі інші залишаються на місці, а не перескакують чорт зна куди як в традиційній німецькій розкладці.

Відкриваємо розкладки для Німеччини:

cd /usr/share/X11/xkb/
sudo vim symbols/de

Додаємо розкладку з наступними клавішами (наслідується від базової американської):

xkb_symbols "germanqwerty" {
    include "us(basic)"
    name[Group1]="German (QWERTY)";

    key <AD11>	{ [udiaeresis, Udiaeresis, dead_diaeresis, dead_abovering ] };
    key <AC10>	{ [odiaeresis, Odiaeresis, dead_doubleacute, dead_belowdot ] };
    key <AC11>	{ [adiaeresis, Adiaeresis, dead_circumflex, dead_caron ] };
    key <AE11> {type[Group1]="FOUR_LEVEL_PLUS_LOCK",  symbols[Group1]=
                  [ssharp, question, backslash, questiondown, 0x1001E9E ]};
};

Далі додаємо нову розкладку до списку відомих:

cd /usr/share/X11/xkb/
sudo vim rules/evdev.xml

Знаходимо список розкладок для Німеччини і додаємо туди свій варіант:

        <variant>
          <configItem>
            <name>germanqwerty</name>
            <description>German (QWERTY)</description>
          </configItem>
        </variant>

Далі треба розлогінитись і залогінитись заново, і можна додавати розкладки через аплет панелі робочого стола.

Посилання


Filed under: Кодерство, Конспекти Tagged: deutsch, linux

Покращене запрошення до вводу $ ▮

Кольорове запрошення до вводу дозволяє візуально виділяти місця де ви ввели команду і лог виконання команди.

Для цього, потрібно задати змінну середовища PS1 в файлі ~/.bashrc для звичайного і для суперкористувача.

Наприклад:

export PS1="\[\e[0;34m\]\u@\h : \w\[\e[m\]\n\[\e[0;32m\]\A \$> \[\e[m\]"
export PS1="\[\e[0;34m\]┌─[\u@\h : \w\n└─[\[\e[0;31m\]\A\[\e[0;34m\]]─> \$ \[\e[m\]"

\[Все що поміщається в екрановані квадратні дужки\] – не враховується при обчисленні довжини запрошення, і важливо поміщати в такі дужки невидимі символи, бо довжина запрошення впливає на те як відображатиметься команда наприклад при навігації по історії команд.

\e[0;34m – синій колір, \e[0;32m – зелений, \e[m – повернутись до звичайного кольору. Повний список кольорів наприклад тут.

\u – користувач, \h – ім’я хоста до першої крапки, \w – повний шлях до поточної директорії, \A – час в 24-годинному форматі HH:MM, \$ – #, якщо ефективний UID користувача 0, інакше – $. Більше можна через man bash, в секції PROMPTING.


Filed under: Інструменти, Кодерство Tagged: linux

Асемблер x86 на Linux

Давно хотів познайомитись, але все стримувало те що в дитинстві я почав з синтаксису Intel, і хотів програмувати тут теж з синтаксисом Intel. Пройшло багато років, я забув, тому давайте вивчимо AT & T синтаксис. Потім при потребі можна перевчитись.

Ну й крім того, я знайшов книжку Programming from the Ground Up, в якій все дуже зрозуміло (як для дітей) пояснюють.

Ну дууууже коротка теорія

Перше що потрібно знати – x86 – це архітектура Фон Неймана, тобто код програми і дані зберігаються в одній і тій же пам’яті, і для комп’ютера виглядають однаково. (Щоправда операційні системи можуть обмежувати виконання лише областями з кодом, для того щоб запобігти можливим помилкам, якими можуть скористатись хитрі хакери)

Пам’ять – це довгий список байтів (можуть містити цілі числа від 0 до 255), кожен з яких має свою адресу. Адреса – це просто номер байта. Щоправда ми працюватимемо переважно не з байтами, а зі словами (в 32-х розрядній архітектурі це 4 байти, які можуть приймати значення від 0 до 4294967295). Тому що регістри процесора якраз стільки вміщають. Адреси – це теж слова (4 байти).

Найпростіша програма

Надрукуємо “Привіт, світе!”? О, ні, на ассемблері це надто складно. Давайте напишемо програму яка завершує роботу. Ага. В Unix, програма яка завершує свою роботу має повернути статус код. Статус код останньої виконаної команди можна побачити у спеціальній змінній командної оболонки: echo $?

_start – в лінкера за замовчуванням позначає точку входу в програму. Тобто адресу з якої почнеться її виконання. Можна замінити її наприклад на main, але тоді лінкер, якщо йому не вказати опцію -e main скаже:

ld: warning: cannot find entry symbol _start; defaulting to 0000000008048054

Символ відсотка позначає регістр процесора (наприклад %eax), долар позначає константу (наприклад $1, $0x80 (= 128 в шістнадцятковому записі) ).

Переривання – це місце в коді де контроль передається в якесь інше місце (в ядро). Коли ядро виконає своє переривання – воно поверне контроль нам, і програма продовжить виконання (стан регістрів може змінитись). Щоправда після системного виклику exit контроль нам ніколи не повернуть, але так й було задумано.

Щоб перевірити нашу програму, потрібно виконати команди:

as exit.s -o exit.o
ld exit.o -o exit

Перша створює об’єктний файл. Об’єктний файл – це вже код машинною мовою, але ще не до кінця зібраний. Потрібно передати його лінкеру – програмі яка вміє збирати багато об’єктних файлів в одну програму, та додавати інформацію для того щоб ядро знало як працювати з програмою.

Якщо все пройшло без помилок – можна перевірити роботу:

./exit 
echo $?

Також можна спробувати замінити код повернення в %ebx на якісь інші і подивитись результат.

Опис інструкцій

mov – це інструкція переміщення, яка має два операнди – звідки й куди.

Суфікс l означає розмір даних (long = 4 байти). Інші можливі префікси: b byte = (8 біт); s short = (2 байти (16 біт).

Багато інших інструкцій мають два операнди, як наприклад addl (додавання), subl (віднімання). Але, наприклад, інструкція div приймає єдиний аргумент, бере вміст регістрів %edx та %eax як велике 64-х розрядне число (якщо треба менше, %edx має містити нуль) ділить на переданий аргумент а тоді результат поміщує в %eax, а остачу від ділення в %ebx.

Регістри загального призначення, які можна використовувати як аргументи команд переміщення та арифметичних – це %eax, %ebx, %ecx, %edx, %edi, %esi.

Контроль ходу виконання

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

Виконання має повернути 89 (найбільше в списку). Це вже набагато цікавіша програма.

По-перше, ми маємо дані. Окрім типу .long (4 байти), ми можемо використовувати .byte, .int (2 байти), та .ascii – рядок символів, наприклад .ascii "Hello, world!\n".

По-друге, цікава інструкція movl data_items(,%edi,4), %eax. Лівий її операнд означає взяти дані з адреси data_items, але зсунутись на %edi елементів розміру 4. Тобто це як доступ до елементу масиву. Синтаксис паскудний, в Intel здається писали б data_items + %edi * 4, що виглядає зрозуміліше, але маємо що маємо.

Також, якщо ми хочемо отримати значення за адресою – теж використовуємо дужки. Наприклад – %esp – містить адресу вершини стеку. movl %esp, %eax – збереже цю адресу в %eax, а от movl (%esp), %eax – значення з вершини стеку.

Наступна незнайома інструкція – cmpl. Вона порівнює два чотирибайтові числа (суфікс бачите?), а результат порівняння записує в певні біти регістру %eflags. Про нього я дуже давно написав непогану статтю на CybWiki а потім на вікіпедії, тому в деталі не вдаватимусь.

Після порівняння зазвичай йде інструкція зробити стрибок на певну адресу, якщо виконується умова порівняння. Існують такі інструкції стрибків з умовою: je – стрибати якщо рівні, jg – якщо друге значення було більше за перше, jge – більше або рівне, jl – менше, jle – менше рівне.

incl – збільшує аргумент на одиничку. incl %edi – це те саме що й addl $1, %edi, тільки коротше й швидше працює.

Далі буде

Вже скоро ранок, а hello world ми ще так і не написали. Треба розібратись з написанням і викликом функцій, викликом функцій роботи з файлами, щоб можна було писати в STDOUT. Але це вже завтра, бо це вже й так надто червоноока публікація.

Хоча в книжці там ще йде мова про рекурсію, обробку помилок, бібліотеки функцій, та їх створення, менеджер пам’яті і інші цікаві речі.


Filed under: Кодерство Tagged: linux

Timeout decorator

Декоратор який використовуючи сигнал Unix SIGALRM перериває роботу функції якщо та працює довше ніж задане число секунд:

import signal

class TimeOut(Exception):
    def __init__(self, msg='Time out error'):
        super(Exception, self).__init__(msg)

def on_alarm(signum, frame): # при надходженні сигналу кидати виняток
    raise TimeOut()

def limit_time(t, default=None):
    signal.signal(signal.SIGALRM, on_alarm) # встановити обробник сигналу

    def decorator(f): 
        def decorated(*args, **kwargs):
            signal.alarm(t) # попросити ОС прислати нам сигнал через t секунд
            try:
                return f(*args, **kwargs)
            except TimeOut:
                return default
        return decorated
    return decorator

import contextlib
# Дякую Алекс!
@contextlib.contextmanager
def time_limit(t):
    signal.signal(signal.SIGALRM, on_alarm)
    signal.alarm(t)
    try:
        yield
    except TimeOut:
        pass


import time

@limit_time(5) # працювати не довше 5 секунд
def test():
    for i in range(10):
        print i
        time.sleep(1)

test()

with time_limit(5):
    for i in range(10):
        print i
        time.sleep()


Filed under: Кодерство Tagged: linux, Python

Proxylocal на CentOS

Я б Ruby поставив тільки за те, що лише вона може ганяти proxylocal. :) Proxylocal - це геніальна програма, яка дозволяє захостити будь-який локальний порт на доступному в інтернеті веб-сервері з унікальним доменом, незважаючи на те чи ви з’єднані через NAT чи через якусь іншу дупу. Досить написати:

$ proxylocal 8080
Local server on port 8080 is now publicly available via:

http://luag.t.proxylocal.com/

або

$ proxylocal 8080 --host bunyk
Local server on port 8080 is now publicly available via:

http://bunyk.t.proxylocal.com/

Інсталюється він дуже просто, якщо у вас стоїть Rubygems:

gem install proxylocal

Але якщо ні, то доведеться поставити його і ще кілька пакетів щоб все могло скомпілюватись:

yum -y install ruby gcc ruby-devel rubygems gcc-c++

make: g++: Command not found означає що бракує gcc-c++, а

mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h – що бракує ruby-devel.

P.S. Якщо цікавитесь Ruby – раджу оцей блог.


Filed under: Кодерство, Павутина Tagged: linux, ruby

Скопіювати дерево проекту на інший сервер по трубі

Власне я робив так:

scp -r path/to/source/tree login@host:/path/to/destination/folder

Water valves with spigots

Але потім виявив що scp ходить за символьними посиланнями і копіює все також і там. Від чого іноді зациклюється…

Тому на просторах інтернету мені підказали ідею послати файли через трубу.

Найперша команда – бере вміст директорії, стискає, і посилає стиснені дані в стандартний вивід:

tar czf - path/to/source/tree

І навпаки – прийняти стиснуті дані з stdout і розпакувати їх в поточну директорію.

tar xvzf -

(При цьому директорія tree створиться, якщо дані пакувались з неї.)

Ну і:

ssh login@host "some; commands"

Виконує інші команди на віддаленому сервері. При цьому може приймати щось з stdout, через трубу. Таким чином ця труба веде з сервера на сервер…

І якщо зібрати все до купи:

tar czf - path/to/source/tree | ssh login@host "cd /path/to/destination/folder; tar xvzf -"

Єдина з цим всім проблема – колись таки доведеться вивчити ті всі ключі до tar. :)


Filed under: Інструменти, Кодерство Tagged: linux

Лапки в bash та pss з awk

Є чудова команда для пошуку коду – pss. Ставиться через pip.

Тільки іноді біда – вона шукає рядки , і іноді те що вона знаходить – мінімізований JavaScript. А це означає що це всі файли зліплені в один рядок на кількасот кілобайт. Звісно мінімізований JavaScript мало кого цікавить, і його варто було б відфільтрувати. Але власник проекту сказав що функцію ігнорування такого коду реалізовувати не буде. Що не страшно, бо є труби і awk. AWK – це майже як grep, тільки з більшими можливостями, здається зовсім тюрінг-повна. Я якось рік тому почав її вивчати а потім забув. :)

І от, щоб відфільтрувати задовгі рядки, досить такої програми на awk:

lenght($0) < 1000


І от я пишу:

pss TextToSearch | awk "lenght($0) < 1000"

А воно не фільтрує!

Виявляється, за $0 – спершу береться bash. І echo "$0" дасть нам на виході слово "bash". А echo '$0' – сам "$0". Ну й зрозуміло що length(bash) – таки менше 1000, а якщо точно, то:

$ awk '{ print length(bash)}'
0

Напевне тому що змінна bash не визначена. Бо

$ awk '{ print length("bash")}'
4

awk_sed

І тому – при змішуванні таких екзотичних мов програмування, головне не переплутати що треба екранувати, і хто на які лапки як реагує.


Filed under: Інструменти, Кодерство Tagged: linux

Vim, Vundle, Solarized

Vim – це текстовий редактор, який має кілька менеджерів пакетів. Можливо їх навіть більше ніж в Windows, тому що враховуючи те що найкращий менеджер пакетів для Windows – Cygwin.

Зараз для мене якраз актуально розповісти про те як швидко розгорнути Vim в звичній конфігурації. Розповідатиму мінімально на прикладі теми Solarized.

Отож, перше (нульове – це мати в системі git) що треба зробити – встановити сам менеджер пакетів:

$ git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

Далі – заповнити .vimrc наступним:

"----------- VUNDLE ---------------------
set nocompatible
filetype off

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Bundle 'gmarik/vundle'
Bundle 'altercation/vim-colors-solarized'

filetype plugin indent on     " required!
"------------- END VUNDLE ---------------

syntax enable
set background=dark
colorscheme solarized
set t_Co=16

Додавати пакети треба в .vimrc там де я вже додав два потрібні, за допомогою команди Bundle, параметром якої є репозиторій GitHub, пряме посилання на .git-файл, чи просто назва скрипта на vim.org/scripts.

Після додання пакетів в .vimrc потрібно виконати команду :BundleInstall і вони інсталюються.

Далі виявиться що потрібно налаштувати кольори в відповідному терміналі, в якому ми Vim запускатимемо. В Gvim все і без цього буде нормально. В Cygwin я вже забув як налаштував, а в Terminal 0.4.8 для xfce ось так:

$ wget -O ~/.config/Terminal/terminalrc https://raw.github.com/altercation/solarized/master/xfce4-terminal/dark/terminalrc

Для Guake трішечки складніше:

$ git clone https://github.com/coolwanglu/guake-colors-solarized.git
$ guake-colors-solarized/set_dark.sh

І от маємо обидва термінали з Vim:
solarized vim in terminals


Filed under: Інструменти, Кодерство Tagged: linux, Vim

Vim, Vundle, Solarized

Vim – це текстовий редактор, який має кілька менеджерів пакетів. Можливо їх навіть більше ніж в Windows, тому що враховуючи те що найкращий менеджер пакетів для Windows – Cygwin.

Зараз для мене якраз актуально розповісти про те як швидко розгорнути Vim в звичній конфігурації. Розповідатиму мінімально на прикладі теми Solarized.

Отож, перше (нульове – це мати в системі git) що треба зробити – встановити сам менеджер пакетів:

$ git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

Далі – заповнити .vimrc наступним:

"----------- VUNDLE ---------------------
set nocompatible
filetype off

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

Bundle 'gmarik/vundle'
Bundle 'altercation/vim-colors-solarized'

filetype plugin indent on     " required!
"------------- END VUNDLE ---------------

syntax enable
set background=dark
colorscheme solarized
set t_Co=16

Додавати пакети треба в .vimrc там де я вже додав два потрібні, за допомогою команди Bundle, параметром якої є репозиторій GitHub, пряме посилання на .git-файл, чи просто назва скрипта на vim.org/scripts.

Після додання пакетів в .vimrc потрібно виконати команду :BundleInstall і вони інсталюються.

Далі виявиться що потрібно налаштувати кольори в відповідному терміналі, в якому ми Vim запускатимемо. В Gvim все і без цього буде нормально. В Cygwin я вже забув як налаштував, а в Terminal 0.4.8 для xfce ось так:

$ wget -O ~/.config/Terminal/terminalrc https://raw.github.com/altercation/solarized/master/xfce4-terminal/dark/terminalrc

Для Guake трішечки складніше:

$ git clone https://github.com/coolwanglu/guake-colors-solarized.git
$ guake-colors-solarized/set_dark.sh

І от маємо обидва термінали з Vim:
solarized vim in terminals


Filed under: Інструменти, Кодерство Tagged: linux, Vim

Як в Linux завантажувати аудіо з списків відтворення vk.com?

Зазвичай я не використовував ніяких лишніх інструментів для того аби качати аудіо з вконтакту, бо всі інструменти вже є в лінуксі, досить лише зберегти плейліст в файл audio.html, та виконати:

wget -c `grep https://.*mp3 -o audio.html`

Але тоді каталог заповнюється файлами виду 7b6e2b1e3f81.mp3 і хоча й більшість mp3 плеєрів читають їх теги і нормально керують колекцією музики, все одно важко наприклад чистити каталоги від зайвих, чи копіювати потрібну музику за маскою. Тому я вирішив написати трішки кращий фільтр ніж grep.

Для його використання потрібно вже дві команди:

wget -O list.py https://bunykprogs.googlecode.com/hg/vk_downloader.py
python3 list.py audio.html | sh

Але результат повинен виправдати зусилля. Перший рядочок – “інсталяція” додаткового скрипта, другий – його виконання. Щоб все працювало, ви повинні мати wget, python3 та lxml для python3.


Працює скрипт просто роздруковуючи команди скачування в термінал. Щоб їх виконати, не обов’язково перенаправляти вивід в файл, можна зразу в sh.

Ви можете запитати, а чому я не зробив так аби скрипт сам скачував аудіо, а не генерував код на sh який це робить? Та тому, що з цим я можу зробити наприклад таке:

python3 list.py audio.html | grep "German" | sh # скачати все з словом German в назві файлу
python3 list.py audio.html | wc -l # показати довжину списку.

Хоч одна програма для викачування музики з вконтакту так вміє? От, от.

Код виглядає ось так:

import sys

from lxml import html
from lxml import etree

def clear_param(txt):
    return txt.strip().replace('"', r'\"')

def parse(fl):
    tree = html.parse(fl)
    elements = tree.xpath('//div[@id="initial_list"]//input')
    urls = []
    for el in elements:
        urls.append(el.attrib['value'].split(',')[0])

    elements = tree.xpath('//div[@id="initial_list"]//div[@class="title_wrap fl_l"]')
    for el, url in zip(elements, urls):
        performer = clear_param(el.xpath('b/a/text()')[0])
        title = clear_param(el.xpath('span[@class="title"]//text()')[0])
        print('wget -c -O "{performer} - {title}.mp3" "{url}"'.format(
            url=url, performer=performer, title=title
        ))

def main():
    if len(sys.argv) > 1:
        parse(sys.argv[1])
    else:
        print('Pass file name', file=sys.stderr)


if __name__=='__main__':
    main()

Filed under: Інструменти, Кодерство, Павутина Tagged: музика, linux, Python