Мини заметки — выпуск 11

8 апреля 2013

Темы выпуска: объединение нескольких Git-репозиториев с сохранением истории коммитов, управление свопом в Linux, вывод дерева процессов в Erlang, определение объема памяти, занимаемого контейнерами в Scala, и не только. Предыдущие выпуски: десятый, девятый, восьмой, седьмой.

1. Открыл для себя Vagrant

Vagrant — это такой инструмент для управления виртуальными машинами. С его помощью вы можете быстро создать dev-окружение, а затем установить в нем требуемые СУБД, компилятор языка программирования и тд. Все это для того, чтобы не засорять хост-систему.

Идем на http://downloads.vagrantup.com/, выбираем версию Vagrant, качаем и устанавливаем пакет для вашей системы. Затем скачиваем, устанавливаем и запускаем образ гостевой ОС:

vagrant box add precise64 http://files.vagrantup.com/precise64.box
vagrant init precise64
vagrant up

Заходим в гостевую систему по SSH:

vagrant ssh

Попадаем в самую обычную Ubuntu 12.10 x64, работающую под VirtualBox.

2. Сколько памяти требуется для хранения списка в Scala?

Создаем файл memusage.scala со следующим кодом:

object Application extends App {
  val runtime = Runtime.getRuntime()
  def getMemory() = runtime.totalMemory() - runtime.freeMemory()
  val count = 1000000
  val start = getMemory()
  var lst = List[Int]();
  for(t <- 1 to count) lst = t :: lst
  val end = getMemory()
  println("Approximate cell size: " + (end - start).toDouble / count)
}

Компилируем-запускаем:

scalac memusage.scala
scala -cp . Application

На моей машине (x64) получилось, что на один элемент списка тратится примерно 39 байт оперативной памяти. Хотя, учитывая представление списков в Scala, должно быть 8 байт под указатель на следующий элемент списка, 8 байт под указатель на данные и 4 байта под Int, итого 20 байт. Несоответствие можно объяснить боксингом, а также необходимостью поддержания структур данных, используемых сборщиком мусора.

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

3. Управление swap’ом в Ubuntu

Информация о свопах:

swapon -s

Выключить своп:

sudo swapoff -a

Включить своп:

sudo swapon -a

Уменьшить агрессивность свопинга:

sudo sysctl vm.swappiness=10

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

В Linux переменные sysctl прописываются в /etc/sysctl.conf.

4. Как написать анонимную рекурсивную функцию на Scala

Тут весьма кстати приходится тот факт, что функции в Scala являются объектами:

val fact = new Function1[Int,Int] {
  def apply(x:Int):Int = if(x==1) x else x * apply(x-1)
}

Взято со StackOverflow.

5. Настройка xinetd в Ubuntu

Демон xinetd бывает удобен, например, когда нужно предоставить кому-нибудь возможность запускать некий сценарий в системе, при этом не предоставляя полноценных прав в этой системе.

Устанавливаем xinetd:

sudo aptitude install xinetd

Создаем сценарий /usr/bin/xinetd-test следующего содержания:

#!/usr/bin/env perl

use strict;
use warnings;

$| = 1;

print "Hello. What is your name?\n";
my $name = <STDIN>;
$name =~ s/[\r\n]//g;
print "Nice to meet you, $name!\n";

Говорим:

sudo chmod a+x /usr/bin/xinetd-test

В файл /etc/services дописываем:

elite           31337/tcp

В /etc/xinetd.conf добавляем:

service elite
{
socket_type = stream
protocol = tcp
wait = no
user = eax
server = /usr/bin/xinetd-test
instances = 20
}

Перезапускаем xinetd:

sudo service xinetd restart

Теперь telnet’имся к порту 31337.

6. Как получить список уязвимостей в используемом ядре Linux

Как вы считаете, много ли дыр имеет используемое вами в данный момент ядро Linux? Запишите вашу оценку на бумажке, а затем выполните команду:

(uname -s; uname -m; uname -r; uname -v) | \
   curl https://uptrack.api.ksplice.com/api/1/update-list/ \
   -L -H "Accept: text/text" --data-binary @-

Однострочник украден с OpenNet. Подробности о Ksplice и обновление ядра Linux на лету можно прочитать здесь.

7. Сидим в Skype с двух аккаунтов

Знаете ли вы, что в Skype можно сидеть с нескольких аккаунтов одновременно?

Команда:

skype --secondary

… в Linux и:

skype.exe /secondary

… в Windows запускает второй экземпляр Skype, в котором вы можете залогиниться под другим аккаунтом. Например, в одном Скайпе у вас может быть личный аккаунт, а во втором — рабочий.

8. Вывод дерева процессов в Erlang

Следующий код, выполненный в консоли Erlang’а, выводит дерево процессов:

P = fun(Supervisor, supervisor, SupPid, S) ->
      { Supervisor, supervisor,
        [ S(Mod, Type, Pid, S)
          || {Mod, Pid, Type, _} <- supervisor:which_children(SupPid)
        ]
      };
    (Module, Type, _Pid, _Self) ->
      { Module, Type, [] }
    end.

P(main_sup, supervisor, whereis(main_sup), P).

Здесь main_sup — имя супервизора, с которого начнется построение дерева.

9. Как в Linux изменить заголовок окна терминала

Следующая команда позволяет установить произвольный заголовок окна терминала:

echo -ne "\033]0;your title here\007"

При желании можно замутить скрипт или, возможно, алиас.

10. Объединение репозиториев без потери истории коммитов

Есть репозиторий dependency, который нужно полностью переместить в каталог apps репозитория project, сохранив при этом историю коммитов. В обоих репозиториях разработка ведется в ветках под названием dev.

cd ~/temp
git clone git@bitbucket.org:afiskon/dependency.git
cd dependency
git checkout dev

git remote rm origin
mkdir -p apps/dependency
mv * apps/dependency
mv .gitignore apps/dependency
git add .
git commit -am 'prepared for merging into project repository'

cd ..
git clone git@bitbucket.org:afiskon/project.git
cd project
git checkout dev

git remote add dependency_remote ../dependency
git pull dependency_remote dev
git remote rm dependency_remote

git commit -am 'dependency is now placed in ./apps'
git push origin HEAD

В действительности, все это происходило с проектом, написанным на Erlang, в связи с чем требовались также правки rebar.config, размещение файлов .gitkeep в каталогах ebin, а также еще что-то, о чем я, к сожалению, уже позабыл. За основу здесь можно взять код ErlyVideo.

Дополнение: Мини-заметки — выпуск 12

Метки: .


Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.