Tar: как разархивировать multipart-архив в командной строке

Разархивировать tar-архив, состоящий из множества частей, из командной строки можно с помощью следующей команды:
cat archive.tar.* | tar xvf -

Ubuntu 14.04: как удалить все старые ядра

При загрузке обновлений Ubuntu может жаловаться, что на диске /boot недостаточно свободного места. Скорее всего, это значит, что там хранятся старые версии ядра. Удалить их можно следующим образом:
сначала выясняем, какая версия ядра используется в данный момент, с помощью команды:
uname -r
Далее выводим список других установленных ядер:
dpkg -l linux-{image,headers}-"[0-9]*" | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e '[0-9]'
и убеждаемся, что в этом списке нет используемого ядра.
Далее можно переправить вывод предыдущей команды на вход команды "sudo apt-get -y purge":
dpkg -l linux-{image,headers}-"[0-9]*" | awk '/^ii/{ print $2}' | grep -v -e `uname -r | cut -f1,2 -d"-"` | grep -e '[0-9]' | xargs sudo apt-get -y purge
После этого все ядра из списка будут удалены.
Источник.

Git: как объединить все коммиты в один

Чтобы объединить все предыдущие коммиты в один (например, чтобы удалить всю историю), можно воспользоваться командой:
git rebase --root -i
После этого список всех коммитов откроется в текстовом редакторе, и напротив каждого из них, кроме первого, нужно будет заменить слово "pick" на "squash". Тогда все предыдущие коммиты будут включены в тот, который находится на первом месте в списке. Затем его можно отредактировать:
git commit --amend --author "Name <e-mail>" --date="$(date -R)" 
Но можно сделать это быстрее с помощью команды:
git reset $(git commit-tree HEAD^{tree} -m "commit message")
которая создаст новый коммит на основе всего существующего дерева.
В обоих случаях при публикации изменений необходимо добавлять опцию "-f":
git push -f

Qt 5.4: Отладка запуска приложения из командной строки

При развертывании приложения написанного с помощью Qt и, в частности, QML иногда полезно посмотреть, какие Qt и QML модули оно пытается найти. Особенно, если оно их найти не может. Например, в случае следующих ошибок:
This application failed to start because it could not find or load the Qt platform plugin "xcb" или
module "QtQuick.Window" is not installed Для этого можно выставить две переменные окружения:
QT_DEBUG_PLUGINS=1 - добавит вывод в консоль информацию о том, какие Qt плагины и где приложение пытается найти, и
QML_IMPORT_TRACE=1 - добавит вывод в консоль аналогичную информацию о модулях QML.
Ну и упомянутые выше ошибки можно вылечить, выставив следующие переменные окружения:
QT_QPA_PLATFORM_PLUGIN_PATH=/path_to_qt/Qt/5.4/gcc_64/plugins - для того, чтоб приложение смогло найти плагин xcb, и
 QML2_IMPORT_PATH=/path_to_qt/Qt/5.4/gcc_64/qml/ - для того, чтобы приложение смогло найти установленные модули QML

Ubuntu 14.04: как автоматически запустить скрипт после запуска ssh

В Ubuntu 14.04 по умолчанию в качестве менеджера загрузки системы используется upstart. Он отвечает в том числе за загрузку сервисов во время загрузки системы и еще он event-based. Поэтому, чтобы заставить свой скрипт выполняться, например, сразу после загрузки ssh, нужно создать такой файл конфигурации для upstart:
description ""
author ""

start on started JOB=ssh
script
    exec /full/path/to/script &
end script
и поместить его в каталог  /etc/init с расширением .conf (например, start_my_script.conf).
Полное описание возможностей upstart можно найти здесь.

Ubuntu 14.04: разрешить сохранение core-файла

В Ubuntu 14.04 по умолчанию при падении приложения все сведения о нем перенаправляются в Apport (правила перенаправления находятся в этом файле: /proc/sys/kernel/core_pattern), которая собирает информацию о системе и генерирует отчет. Крэши пользовательских приложений она пропускает дальше в систему, но по умолчанию генерация core-файлов в системе запрещена. Включить ее можно выполнив команду:
ulimit -c 10000
где 10000 - это размер core-файла в блоках по 1кб. По умолчанию это число выставлено в 0. За сессию его можно изменить один раз, если нужно поменять еще раз - придется логиниться заново. Ну и логи Apport находятся по адресу: /var/log/apport.log. Там, например, будет сообщение об ошибке, если core-файл оказался большего размера, чем разрешено в ulimit -c. Если же значение ulimit -c не превышено, core-файл будет сгенерирован в той же директории, в которой находится упавшее приложение.

Linux: stress - утилита для организации нагрузки на систему

Stress - полезная утилита для Linux, которая позволяет организовать различные типы нагрузок на систему.
Пример использования:
stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

Ubuntu 14.04: Невозможно подключиться к WiFi после пробуждения из спящего режима

Иногда после пробуждения из спящего режима Ubuntu 14.04 не может подключиться к известной WiFi сети. Проблема лечится следующим образом: надо создать исполняемый файл в каталоге /etc/pm/sleep.d/
sudo touch /etc/pm/sleep.d/wakenet.sh
sudo chmod +x /etc/pm/sleep.d/wakenet.sh
и поместить в него следующее содержимое:
#!/bin/bash
case "$1" in
thaw|resume)
sudo nmcli nm sleep false
sudo pkill -f wpa_supplicant
;;
*)
;;
esac exit $?
В некоторых случаях проблема остается и после этого, тогда можно пробовать после пробуждения выполнить:
sudo service network-manager restart
Решение взято с askubuntu.

Vim: убрать лишние пробелы в конце всех строк

Чтобы в Vim убрать лишние пробелы в конце всех строк, можно воспользоваться командой:
:%s/\s\+$//
команда %s аналогична команде s в sed, о которую я упоминал в одном из предыдущих постов. Точно так же сначала следует регулярное выражение, которое определяет, что нужно найти, затем - то, на что найденные символы заменить. Части команды разделены символом /.
В данном случае регулярное выражение "\s\+$" описывает пробелы, в количестве один или больше, расположенные в конце строки. Вторая часть команды пустая, поэтому найденные пробелы будут просто удалены. Так же пустую часть команды можно опустить:
:%s/\s\+$
Ну и можно отредактировать vimrc так, чтобы эта замена происходила по нажатию на кнопку F5, если добавить в него строчку:
nnoremap <silent> <F5> :let _s=@/<Bar>:%s/\s\+$//e<Bar>:let @/=_s<Bar>:nohl<CR>

Vim в качестве HEX-редактора

Отобразить файл в HEX в Vim можно командой:
:%!xxd
Чтобы вернуться обратно:
:%!xxd -r
Надо отметить, что в Vim нет HEX-режима, а эти команды на самом деле просто прогоняют данные из Vim через утилиту xxd.

Перенаправить вывод tail -f через grep в файл

Команда
tail -f log.txt | grep "expression"
позволяет, например, фильтровать лог выполняющейся программы. Однако, чтобы перенаправить ее вывод в файл, нужно вызывать grep с флагом --line-buffered. В этом случае grep будет писать в файл не при заполнении буфера, а при получении символа новой строки.
В итоге команда должна выглядеть так:
tail -f log.txt | grep --line-buffered "expression" >> file.txt

Создание и установка разделяемых библиотек (shared libraries) в Linux

Как собрать код в разделяемую библиотеку с помощью gcc

gcc -fPIC -c helloworld.c -o helloworld.o
gcc -shared -Wl,-soname,libhelloworld.so.1 -o libhelloworld.so.1.0.1 helloworld.o
Первая команда компилирует исходник helloworld.c в объектный файл helloworld.o, вторая - создает из объектного файла разделяемую библиотеку helloworld.so.1.0.1.

char, unsigned char и побайтовое чтение из файла размера очередной порции данных

Часто данные в файле записываются в виде: сколько-то байтов - размер очередной порции, затем - собственно данные. Изучал код на Си, читающий такой файл, и наткнулся на следующую конструкцию:
char sizeLow, sizeHigh;
int size;
FILE * pFile;
pFile = fopen ("myfile.bin" , "rb");
fread (&sizeHigh, 1, 1, pFile);
fread (&sizeLow, 1, 1, pFile);
size = (sizeHigh << 8) | sizeLow; 
Выяснилось, что после такого чтения size легко может оказаться отрицательным, даже если и был записан вполне себе положительным (например, если первый байт был равен 0x1, а второй - 0xff).

Linux: запуск программы на одном процессоре

В многопроцессорных системах иногда полезно в целях отладки (или, например, измерения производительности) запускать программу только на одном процессоре. Это можно сделать в Linux с помощью команды:
taskset -c 0 ./program_name
Это команда запускает процесс с заданным свойством CPU affinity; оно, в свою очередь, определяет список процессоров, на которых планировщик может запускать данный процесс. В данном примере оно позволяет планировщику запускать заданный процесс только на ядре номер 0. Можно также указать несколько номеров через запятую.

QtCreator: Could not load shared library symbols при попытке отладки консольного приложения

При поптыке отладки консольного приложения в QtCreator столкнулся с такой ошибкой:
Could not load shared library symbols for library_name.so. Do you need "set solib-search-path" or "set sysroot"?
При этом все пути в системе были выставлены правильно. Решение оказалось довольно простое - на вкладке Projects->Run нужно снять галочку "Run in terminal". Тогда приложение запускается в консоли QtCreator, а не в отдельном терминале и все библиотеки находятся.

Одновременное отображение вывода программы в терминале и запись его в файл

Чтобы и увидеть вывод программы в терминале и записать его в файл, можно воспользоваться командой tee:
program | tee filename.log

Linux: Получение количества потоков в процессоре в командной строке

Чтобы узнать количество потоков, которые процессор может одновременно выполнять, можно выполнить команду:
cat /proc/cpuinfo | grep processor | wc -l
Выводится сожержимое файла /proc/cpuinfo, из него берутся строчки, содержащие слово "processor", а команда "wc -l" считает количество поданных ей на вход строчек. Вывод этой команды, например, удобно передавать в make для параллельной сборки:
make -j 'cat /proc/cpuinfo | grep processor | wc -l'
UPD: более короткая весрия той же команды:
grep processor /proc/cpuinfo | wc -l

Linux: команды командной строки для просмотра размера директорий

Команда:
ls -l
не дает размера директории. Чтобы узнать его, можно воспользоваться командой:
du -hs /path-to-directory
-h дает размеры в "human readable" виде,
-s - summary, без нее команда du выдаст не только размер заданной директории, но также и размеры всего, что в ней находится.
Команда:
du -h --max-depth=1 /path-to-directory
Выдаст размеры всех поддиректорий в заданной директории. Ну и для просмотра занятого и свободного места на диске можно воспользоваться командой: df

Vim: переход на новую строку по Enter

В Vim в normal mode можно добавить пустую строку после текущей строки с помощью команды 'o' и перед текущей строкой — с помощью команды 'O'. Однако при этом Vim переходит в режим insert mode. Чтобы этого не происходило, я добавил в файл .vimrc такой маппинг:
nmap <CR> o<Esc>
Теперь по нажатию на Enter будет добавлена пустая строка после текущей, курсор перейдет на нее, а Vim останется в normal mode.

Vim: дерево каталогов

Иногда бывает удобно иметь в Vim дерево каталогов как в большинстве IDE. Оно реализовано в отдельном плагине — NERD Tree. При его включении в левой части экрана открывается дополнительное окно (так же, как если была вызвана команда :vsplit) с деревом каталогов, на которую можно переходить с помощью комбинации клавиш Ctrl+W+W, по ней можно перемещаться, открывать каталоги и открывать файлы для просмотра и редактирования

Ubuntu 14.04: расширение пути поиска библиотек по умолчанию

Если для запуска бинарника требуются библиотеки, которые не установлены в системе, а перекомпилировать бинарник нет желания или возможности, можно указать системе, где искать недостающие библиотеки. Один путь - это модифицировать LD_LIBRARY_PATH, добавив туда недостающий путь. Впрочем, это решение часто критикуется (1, 2, 3). Другой вариант - добавить недостающий путь в ldconfig. При этом нет необходимости изменять файл libc.conf - можно создать отдельный файл для своей конфигурации.
Нужно создать файл:
/etc/ld.so.conf.d/filename.conf
записать туда путь к необходимым библиотекам, и затем выполнить команду
sudo ldconfig
которая обновит кэши. Теперь при запуске бинарников заданный путь будет также использоваться для поиска библиотек.

Linux: cложить все числа в файле в командной строке

В предыдущем посте было написано, как выбрать все числа из файла. В итоге у меня получился в файл в каждой строке которого находится число. Эти числа можно обработать с помощью awk. Например, очень легко можно сложить все числа:
awk '{s+=$1} END {print s}' filename

Linux: вывод в консоль всех чисел из файла

Для выборки всех чисел из файла воспользуемся утилитой grep:
grep -o "[0-9]" filename
[0-9] - регулярное выражение, в которое попадают только цифры от 0 до 9. Флаг -о заставляет grep выводить не всю найденную строку, а только то, что задано регулярным выражением. Проблема в том, что таким образом grep выведет все цифры, нам же нужны все числа. Нужно дописать регулярное выражение:
grep -oE "[0-9]{1,}" filename
Флаг -Е разрешает расширенные регулярные выражения (extended regexp), а {1,} определяет длину предыдущего выражения. В нашем случае, будут найдены все последовательности из цифр длиной от одного символа и больше, то есть все числа. Можно также ограничить максимальную длину числа (например, не больше 5 цифр), указав верхнюю границу в выражении:
grep -oE "[0-9]{1,5}" filename
В следующем посте пример того, как обработать полученный вывод.

Linux: вывод в консоль заданных строк из файла

Чтобы вывести в консоль только строки, заданные определенным регулярным выражением, достаточно выполнить команду:
sed -n '/regexp/p' filename
Без опции -n sed выведет помимо заданных строк все строки файла, на место regexp надо подставить регулярное выражение, на место filename - имя файла, /p - это имя команды sed.
Строки можно также выводить по вхождению подстроки:
sed -n '/some_words/p' filename
по номеру:
sed -n '5p' filename
и по диапазону номеров:
sed -n '5,9p' filename
Диапазон также можно задавать двумя подстроками или двумя регулярными выражениями:
sed -n -e '/some_words_1/,/some_words_2/p' filename
sed -n -e '/regexp1/,/regexp2/p' filename
Также можно вывести строки, начиная от заданной и до конца файла:
sed -n '/regexp/,$p' filename

Qt 5.3 QML: Владение объектами С++

По умолчанию объекты, созданные в коде С++ и переданные в QML через Q_INVOKABLE методы или слоты передаются во владение Javascript. То есть если в QML передается указатель на объект, созданный в коде С++ динамически посредством вызова оператора new(), сборщик мусора Javascript удалит его по своему усмотрению: если на него не будет ссылок в Javascript, не будет родительского объекта (QObject::parent() будет пуст), или будет вызван деструктор соответствущего QQmlEngine. Это поведение можно изменить с помощью вызова статического метода:
void QQmlEngine::​setObjectOwnership(QObject * object, ObjectOwnership ownership)
Таким образом, если выставить только что созданному объекту значение QQmlEngine::CppOwnership, владение останется на стороне кода С++, и сборщик мусора его не тронет.