Split Screen with Screen in Linux - Работаем в screen



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

Может быть кому-то будет полезен мой набор шоткатов, не идеально (как и все в этом мире), но мне хватает:

Ctrl+a - c - создаст новую "вкладку", ещё один терминал
Ctrl+a - n - переход к следующей вкладке
Ctrl+a - 1..0 - переход к вкладке по её номеру, т.е. если я хочу перейти ко второй вкладке то я должен выполнить Ctrl+a - 2
Clrl+a - a - переход к предыдущей открытой вкладке, то есть вы в пятой а предыдущая была вторая, так можно быстро перейти без ввода номера вкладки
Ctrl+a - " - выбор активного терминала для текушей "вкладки" (двойная кавычка через шифт)
Ctrl+a - Shift+a - переименование текущей вкладки, бывает удобно именовать вкладки
Ctrl+a - k - "убить" текущую вкладку, в случае если по каким-то причинам сеанс завис или сломался вывод например
Ctrl+d - это стандартный выход из сеанса, "вкладка" скрина тоже будет закрыта
Ctrl+a - ? - шпаргалка по хоткеям

Ctrl+a - Esc - перемещение по выводу screen, оно же режим копирования, скроллим вверх и вниз стрелками или PgUp/PgDn
В режиме копирования/скроллинга:
q - выход в нормальный режим
0 - переход в начало строки
$ - переход в конец строки
Ctrl+b - на страницу вверх
Ctrl+d - на страницу вниз
Space - первое нажатие - начало выделения, второе нажатие после перемещения скопирует выделенное в буфер обмена screen
Ctrl+] - вставить содержимое буфера screen
Копирование происходит в некий "внутренний" буфер screen, а не в глобальный клипборд вашей OS. Если у вас macos или linux, то есть варианты.

Разделения экрана (из видео)
Ctrl+a - Shift+s - разделяем по горизонтали
Ctrl+a - | - разделяем по вертикали (пайп вводится с шифтом конечно, посмотрите на свою клавиатуру)
Ctrl+a - Shift+x - удалить текущее разделение (ту зону, в которой сейчас находится курсор)
Ctrl+a - Tab - перейти к следующей области разделения
С этими функциями нужно поэкспериментировать чтобы до конца понять принцип действия.


Ставим скрин (если вдруг его нет):
sudo apt-get install screen

Запускаем screen:
tatuin@luke# screen

Выходим из screen, но оставляем его в процессах, чтобы при следующем заходе на сервер снова подключиться к нему (это по-модному называется detach):
Ctrl+a - d

Подключаемся к оставленному включенным на сервере screen:
tatuin@luke# screen -x

Уже этого небольшого набора мне хватает чтобы полностью отказаться от вкладок терминала с разными переключениями от системы к системе, если они вообще предусмотрены в клиенте :)
Если знаете ещё что-то полезное - пишите в комментариях - я дополню заметку.

P.S.: ещё хорошо бы для удобства немного донастроить скрин, чтобы показывать вкладки, для этого нужно добавить в файл ~/.screenrc следующие настройки:
startup_message off
caption always
caption string "%{kw}%-w%{wr}%n %t%{-}%+w"
defutf8 on
defscrollback 5000
Все пока. Настройки легко гуглятся, как обычно :) Большая дока есть например тут, надеюсь будет живо.

Осваиваем VIM

А нафига, спросите вы. А для расширения кругозора, например. Времени это займет час. Всяко полезнее чем просто на лепре протупить.

Ок, что читать. Есть онлайн курс, интерактивный, вот тут. Это раз.

Есть ещё встроенный туториал, для этого надо будет поставить сам вим, правда. Вот так (ubuntu/debian)
sudo apt-get install vim
vimtutor
Я не пожалел. Думаю в гипотетически сложной ситуации без никакого редактора кроме вима например эти знания могут здорово помочь. Меня впечатлили и табы и продвинутые плюшки для копирования-редактирования и обилие всяких приблуд. В общем этого часа он определенно стоит я считаю. Как основной я его конечно использовать не буду, все же шторм мне как-то ближе к телу, вим по сравнению с ним жуткий хардкор, но вот вместо mcedit буду пользовать. Приятнее заметно, хоть и требует некоторого навыка.

Как быстро сделать спрайт? Ubuntu

Спрайт (в вебмастерской терминологии) есть фиговина призванная уменьшить количество запросов к серверу путем аккамулирования в себе кучи картинок которые используются в верстке. При помощи "хитрых" приемов верстки в нужном месте появляется нужный кусочек изображения из спрайта и выглядит как полагается, но при этом на 100 показанных картинок (например) реально у сервера запрашивается только одна - спрайт который всю эту мелочевку содержит. Как ими правильно пользоваться, как верстать и как не злоупотреблять ими - читайте у настоящих Верстальщиков. "Я не настоящий сварщик" ©

Я тут хочу написать о другом. Допустим есть у нас NN картинок для спрайта. Как спрайт сделать. Ну как, берём открываем там фотошоооп или гимп или ещё какой-нибудь графический редактор и начинаем все засовывать туда и записывать координаты где чего лежит. Теоретически все так и должно быть, профессионалы я думаю так примерно и делают. Я не профессионал-верстальщик и вообще не верстальщик, но зато я большой лентяй. Поэтому рассмотрим лентяйский пример ниже :)

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

В общем суть примера. Есть NN картинок одинакового разрешения и типа. У меня это было 4 png-шки 128x128. Когда я поставил и открыл Gimp мне сделалось нехорошо. Опять надо все это вспоминать, считать, двигать подгонять.. Пошел гуглить на предмет того как бы это в гимпе сделать автоматически а нагуглил вот что. Есть консольная утилитка convert, часть пакета imagemagick, я даже когда-то давно ей пользовался но забыл уже про это. Она замечательно с этой задачей справляется.

ставим imagemagick
sudo apt-get install imagemagick
это у нас ман по конверту, ага
man convert
идем в папку с файлами из которых будем лепить спрайт
cd 4sprite-test/
ls
facebook.png  github.png  google.png  twitter.png
теперь берем и все эти файлы склеиваем вот так
convert *.png +append sp-big.png
ls
facebook.png  github.png  google.png  sp-big.png  twitter.png
если надо ещё и изменить размер исходных файлов то делаем так
convert *.png -resize 64x64 +append sp-med.png
Думаю даже не надо пояснять что к чему, все понятно из ключей к конверту. Единственное что в примере под маску попадают все файлы *.png в папке. И если оттуда не убрать сгенеренный спрайт то при повторном запуске в новый созданный спрайт он попадет тоже. Повнимательнее с рекурсией и маской:)

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

Как получить md5 хэш строки или файла в консоли, Ubuntu

Это полная ерунда понятное дело, но я забываю постоянно. Поэтому законспектирую.
# для файла совсем просто
md5sum file.txt

# для строки чуть замороченнее
echo -n 'string ololo jj' | md5sum
Чтобы понять почему так и что за ключи смотрим man md5sum и man echo.

Декоратор для mysql - node.js + express.js

dbConfig.js
module.exports = {
  user: 'root',
  password: 'root',
  host: '127.0.0.1',
  database: 'db'
};
db.js
/**
 * decorator for mysql
 */
var mysql = require('mysql'),
    dbConfig = require('./dbConfig'),
    conn = mysql.createConnection(dbConfig);

// standard query
exports.q = function(sql, callee, next){

  if (typeof(callee) != 'object' || !(callee instanceof Array)) {
    calleeSend = [];
  } else {
    calleeSend = callee;
  }

  conn.query(sql, calleeSend, function(err, qres){
    if (err){
      if (typeof(callee) == 'function') {
        return callee(err);
      } else if (typeof(next) == 'function') {
        return next(err);
      } else {
        console.log('Uncaught DB error: ', err);
        console.log('Uncaught error in query: ', sql);
      }
    }

    try {
      if (typeof(callee) == 'function') {
        callee(err, qres);
      } else if (typeof(next) == 'function') {
        next(err, qres);
      }
    } catch(e) {
      next(e);
    }

  });
};

// get row
exports.getRow = function(sql, callee, next){

  if (typeof(callee) != 'object' || !(callee instanceof Array)) {
    calleeSend = [];
  } else {
    calleeSend = callee;
  }

  conn.query(sql, calleeSend, function(err, qres){
    if (err){
      if (typeof(callee) == 'function') {
        return callee(err);
      } else if (typeof(next) == 'function') {
        return next(err);
      } else {
        console.log('Uncaught DB error: ', err);
        console.log('Uncaught error in query: ', sql);
      }
    }

    row = (qres[0]) ? qres[0]: false ;

    try {
      if (typeof(callee) == 'function') {
        callee(err, row);
      } else if (typeof(next) == 'function') {
        next(err, row);
      }
    } catch(e) {
      next(e);
    }

  });

};

// last insert id
exports.lastId = function(next){

  conn.query("SELECT LAST_INSERT_ID() as id", function sres(err, qres){
    var id = (qres[0].id) ? qres[0].id: false ;

    try {
      next(err, id);
    } catch (e) {
      return next(e);
    }

  });
};

// calc found rows
exports.foundRows = function(next){
  conn.query("select found_rows() as cnt", function(err, qres){
    var cnt = (qres[0].cnt) ? qres[0].cnt : false ;

    try {
      next(err, cnt);
    } catch (e) {
      return next(e);
    }
  });
};
Сам mysql — вот этот модуль npm install mysql

Я вообще не уверен что это правильно полностью, надо бы узнать мнение корифеев (где б найти ещё их), но то что оно работает и это вообще возможно и не слишком замороченно - очень радует.

UPD: и правильно думал, ошибка здесь есть - см. Node.js + MySQL FOUND_ROWS()