Linux: как рекурсивно заменить пробелы в названии файлов и директорий

Файлы с пробелами в имени иногда неудобно обрабатывать в скриптах, поэтому я стараюсь их не использовать. Но если есть директория, в которой находятся файлы с пробелами в именах, и хочется их все переименовать так, чтобы вместо пробелов использовались, например, символы подчеркивания, то в Linux это легко сделать с помощью утилиты find:
find /path_to_dir/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;
Флаг -depth указывает утилите, что сначала надо обрабатывать содержимое текущей директории, а только потом саму директорию (что позволяет нам сначала переимновать все файлы внутри директории и только потом ее саму); флаг -execdir позволяет выполнить слудующую за ним команду из текущей директории; rename - утилита, установленная в Ubuntu по умолчанию. В итоге find ищет в заданной директории все файлы и поддиректории с пробелами в именах, а rename - заменяет пробелы на подчеркивания.

С++: Безопасность относительно исключений при вызове функций

Этот пост - перевод статьи Герба Саттера: GotW #102: Exception-Safe Function Calls.

Простой вопрос

1. Что вы можете сказать о порядке выполнения функций f, g и h и выражений expr1 и expr2 в приведенных ниже фрагментах кода? Предпалагается, что expr1 и expr2 не содражат в себе вызовов других функций.
// Пример 1(a)
//
f( expr1, expr2 );
// Пример 1(b)
//
f( g( expr1 ), h( expr2 ) );

Вопросы посложнее

2. Разбирая доставшийся вам в наследство код, вы наткнулись на следующий фрагмент:
// Пример 2
 
// В заголовочном файле:
void f( T1*, T2* );
 
// В месте вызова:
f( new T1, new T2 );
Есть ли в этом коде проблемы с безопасностью относительно исключений или любые другие проблемы? Объясните.

3. Продолжая изучать старый код, вы обнаруживаете, что кому-то не нравился код, приведенный в примере 2, и позднее он был изменен на:
// Пример 3
 
// В заголовочном файле:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );
 
// В месте вызова:
f( std::unique_ptr<T1>{ new T1 }, std::unique_ptr<T2>{ new T2 } );
Какие улучшения привнес новый подход относительно старого (и привнес ли вообще)? Остались ли проблемы с безопасностью относительно исключений? Объясните.

4. Покажите, как можно реализовать функцию make_unique, которая бы решала проблемы с безопасностью в примере 3, и которую можно было бы вызывать следующим образом:
// Пример 4
 
// В заголовочном файле:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );
 
// В месте вызова:
f( make_unique<T1>(), make_unique<T2>() );

Как открыть несколько соединений Tor для использования в Python скриптах (на примере Ubuntu)

В предыдущем посте я показал, как можно использовать соединение Tor из Python-скрипта (а также как устанавливать и запускать Tor-сервис в Ubuntu). Преимущество того подхода (по сравнению с использованию Privoxy в качестве прослойки мeжду SOCKS и HTTP) заключается в том, что он легко масштабируется: можно открыть любое (на сколько хватит аппаратных ресурсов) количество соединений и каждому Python процессу дать по одному прокси-порту (c Privoxy это тоже можно сделать, но несколько сложнее).
Здесь же я проведу в качестве примера Bash-скрипт, который открывает заданное количество Tor-соединений и для каждого соединения запускает два Python-скрипта.

Python3: как выполнять HTTP запросы через Tor (на примере Ubuntu)

В этом посте я опишу как пользоваться Tor в своих Python-скриптах. Зачем это нужно? Например, чтобы изменить свой видимый IP адрес для сервиса, к которому вы обращаетесь.
Нам понадобится установленный Tor и Python (я использую третий, но второй, по идее, тоже должен работать). Многие советуют использовать дополнительный сервис Privoxy между Tor, который работает как SOCKS-прокси и библиотеками Python, которые хотят получить HTTP-прокси, но я не очень понял, зачем, если в Python можно пользоваться SOCKS-прокси напрямую.
У меня установлена Ubuntu, поэтому и весь процесс я описываю для этой ОС. В других, я так понимаю, все должно быть примерно так же (Python-код должен работать в любом случае, разница может быть только с установкой и запуском Tor).

Использование умных указателей в C++

Этот пост - перевод статьи Герба Саттера: GotW #89 Solution: Smart Pointers.

Постановка проблемы

Простой вопрос

1. В каких случаях следует использовать shared_ptr а в каких - unique_ptr? Приведите как можно больше соображенией на эту тему.

Вопросы посложнее

2. Почему практически всегда следует использовать make_shared для создания объекта, которым будут впоследствии владеть shared_ptr? Объясните.

3. Почему практически всегда следует использовать make_unique для создания объекта, которым будет владеть unique_ptr? Объясните.

4. Что такое auto_ptr?

NodeJS: простейший Express сервер

Этот пост в каком-то смысле продолжение поста про простейший NodeJS сервер, принимающий JSON объекты. Помимо того, что сервер может принимать данные извне (в данном случае, с помощью POST-запроса и JSON), хорошо бы чтобы он умел выдавать пользователю web-страницу с имеющимися данными. В принципе, в случае с одной страницей можно было бы вручную дописать сервер из предыдущего поста, но я решил использовать фреймворк Express, который сэкномит время на написание кода, а в дальнейшем позволит легко масштабировать сервер. Более того, Express имеет встроенные средства для генерации HTML кода из шаблонов страниц (я буду использовать EJS), и много других вещей, которые тоже, вполне возможно, пригодятся в дальнейшем.

SparkFun ESP8266 Thing: подключение датчика движения

Стоит такая задача: подключить датчик движения к микроконтроллеру ESP8266, который будет в свою очередь как-нибудь реагировать на движение в поле видимости датчика (в моем примере он будет мигать светодиодом на плате). В качестве датчика движения я буду использовать вот такой PIR сенсор. Про свою ESP8266 The Thing от SparkFun я уже писал, например, здесь: настройка IDE и прошивка. Мне повезло, и мой PIR сенсор работает от 3,3 В, поэтому его можно запитать прямо от платы. Встречаются очень похожие сенсоры, где регулятор напряжения на входе принимает минимум 5 В. В таком случае можно пустить питание прямо на выход регулятора, минуя его (это описано, например, здесь или здесь), потому что сама плата питается от 3,3 В (ну или использовать отдельное питание для PIR сенсора).

SparkFun ESP8266 Thing: подключение к WiFi и выполнение POST-запроса с JSON

Привожу тут пример кода для SparkFun ESP8266 The Thing, который подключается к WiFi и выполняет POST-запрос к указанному серверу. (Про то, как подключить эту плату к компьютеру и прошить я писал здесь). В качестве сервера я использовал NodeJS сервер, который я описывал здесь (этим и объясняется содержание JSON в запросе). Собственно, плата подключается к WiFi и раз в 30 секунд через POST отправляет серверу вот такой JSON:
{
    "var1": "1",
    "var2": "0"
}

Raspberry Pi: как быстро проверить камеру без монитора

Если Raspberry Pi работает без монитора и к ней можно получить доступ только удаленно (пример подобной настройки я описал здесь), то чтобы проверить камеру надо запустить видеопоток в сеть. Можно сделать это с помощью vlc.

  1. Подключаемся к Raspberry по ssh.
  2. Устанавливаем vlc:
    sudo-apt-get update vlc
    
  3. Подключаем драйвер Video4Linux:
    sudo modprobe bcm2835-v4l2
  4. Запускаем видеопоток:
    cvlc v4l2:///dev/video0 --v4l2-width 1920 --v4l2-height 1080 --v4l2-chroma h264 --sout '#standard{access=http,mux=ts,dst=0.0.0.0:12345}' :demux=h264
  5. На компьютере запускаем vlc, открываем меню Media->Open Network Stream, указываем там в качестве источника:
    http://IP.адрес.Raspberry.Pi:12345
    и нажимаем Play.



Ubuntu: первоначальная настройка Raspberry Pi без монитора

Самый простой способ запустить и настроить Raspberry Pi - подключить к ней монитор и клавиатуру, вставить SD карту на которую скопирован установщик NOOBS, и включить. Если же лишнего монитора нет, то можно по-прежнему установить самостоятельно установить Raspbian на SD карту, запустить с этой карты Raspberry Pi, подключиться по ssh (включен по умолчанию) и настроить удаленный рабочий стол. Для этого понадобится только компьютер с Ubuntu (просто потому, что у меня Ubuntu - для других дистрибутивов, Windows и OS X процесс не должен принципиально отличаться), сеть ( и возможность подключиться к ней с помощью Ethernet кабеля), чистая SD карта размером больше, чем образ Raspbian (Raspbian Jessie занимает 4 Гб) и сама Raspberry. Ниже приведена пошаговая инструкция, что надо сделать, чтобы все заработало.

Ubuntu: изменение кодировки id3v2 тегов для всех файлов в папке

Некоторые проигрыватели понимают только Unicode кодировки в id3 тегах. В итоге, если файл, созданный в Windows, содержит теги с кириллицей, то в проигрыватель может показать что-то такое: Ãðàæäàíñêàÿ îáîðîíà.
К счастью, кодировка UTF-8 воспринимается всеми, поэтому ее легко можно использовать вместо любой другой. А переконвертировать теги для всех mp3 файлов в папке в Ubuntu можно следующим образом.
  1. Устанавливаем пакет python-mutagen:
    sudo apt-get install python-mutagen
    
  2. Определяем, в какой кодировке записаны нечитаемые теги: 
    • вот так можно получить список возможных кодировок:
      iconv --list
      
    • копируем нечитаемую строчку в декодер и смотрим, что он скажет,
    • или смотрим на диаграмму.
  3. Проверяем, правильно ли мы определили кодировку: 
    • выполняем команду:
      mid3iconv -p -d -e <source-encoding> input.mp3
      
      где source-encoding - это полученная ранее кодировка, input.mp3 - mp3 файл с нечитаемыми тегами; флаг -p выставляется, чтобы команда не изменяла сам файл, но просто вывела в консоль конвертированные значения тегов;
    • если в консоли появляются читаемые теги - переходим к следующему шагу, если нет - значит, исходная кодировка выбрана неправильно.
  4. Конвертируем все файлы с расширением .mp3 в папке (и рекурсивно во внутренних папках) из заданной кодировки в UTF-8:
    find . -name "*mp3" -print0 | xargs -0 mid3iconv -e <source-encoding> -d 
    
    или для примера выше (файлы, записанные в Windows c кириллицей в тегах часто имеют кодировка CP1251):
    find . -name "*mp3" -print0 | xargs -0 mid3iconv -e CP1251 -d
    

Как починить поврежденные MP3 файлы

Столкнулся с проблемой, что часть файлов из моей mp3 коллекции не проигрывается некоторыми проигрывателями в Ubuntu (единственные проигрыватели, которые проиграли все - Vlc, и Audacity). В итоге нашел бесплатную программу MP3 Diags (есть и под Windows и под Linux), которая автоматически чинит довольно много проблем в mp3 файле. Я просто прогнал максимальный набор тестов и это решило все мои проблемы. Следует отметить, что MP3 Diags по умолчанию может заменять существующие файлы на исправленные. Так же автор упоминает несколько отчетов о крэшах, которые ему присылали, то есть перед тем, как чинить всю свою коллекцию mp3 файлов лучше сначала сделать резервную копию. Почитать подробнее о программе (включая довольно подробную документацию) можно здесь.

Почему не следует использовать std::set (и что стоит использовать вместо)

Этот пост является переводом статьи Мэтта Остерна: Why you shouldn't use set (and what you should use instead).
Все, что находится в стандартной библиотеке С++, находится там по какой-то причине, но это не всегда очевидно, по какой именно. Стандарт - это не руководство, в нем не проводится разделения между базовыми компонентами, которые используются постоянно, и теми компонентами, которые были добавлены в стандарт для редких и специфичных случаев.
Один из примеров - это ассоциативный контейнер std::set (и родственные ему map, multiset, multimap). Иногда использование set действительно имеет смысл, но не так часто, как вы могли бы подумать. Стандартная библиотека предоставляет и другие инструменты, позволяющие хранить данные и совершать выборку данных, и часто можно достичь тех же целей, что достигаются при использовании set, используя при этом более простые, более легковесные и более быстрые структуры данных.

Blogger: настройка блока "Поделиться" от Яндекс

Встроенные в Blogger кнопки "поделиться" не очень удобны: там представлен довольно ограниченный набор соц. сетей, да и сложно заставить их находиться там, где нужно (мне в итоге это не удалось в полной степени). К счастью, Яндекс предлагает свой настраиваемый блок "Поделиться". Проблемы начинаются, если хочется разместить кнопки не только на странице поста, но и на главной под каждым постом в списке, причем так, чтобы при нажатии на кнопку использовалась ссылка именно на пост, а не на страницу, на которой эта кнопка размещена. Для этого нужно использовать дополнительные настройки блока (полный список найтроек можно найти в документации).

Как изменить размер шрифта в SyntaxHighlighter

По какой-то причине в SyntaxHighlighter, который я использую для подсветки синтаксиса в этом блоге, нет опции изменить размер шрифта кода - он задан как 100% от размера шрифта родительского блока. Чтобы изменить его, можно вручную поменять это везде в css-файлах SyntaxHighlighter, но в моем случае, когда я просто гружу все необходимые файлы с сайта самого SyntaxHighlighter, пришлось бы размещать измененные файлы где-то еще и грузить оттуда. Другой подход - это оборачивать блок с кодом (блок <pre>) дополнительным блоком <div> с каким-нибудь собственным классом:
<div class="syntax_wrapper">
<pre class="brush:cpp">
Здесь располагается код на Си++
</pre>
</div>
и у себя в css прописать:
.syntax_wrapper { font-size:80%; }
Теперь размер шрифта для кода будет составлять 80% от размера шрифта для остального текста.

Как определить ip-адрес устройства в локальной сети в командной строке

Иногда полезно получить список ip-адресов всех устройств в подсети или в диапазоне адресов (например, чтобы подключиться по ssh к устройству, у которого нет монитора). Для этого отлично подойдет утилита nmap (распостраняется и для Linux  и для Windows, для Ubuntu она есть в репозиториях).
Вот как это можно сделать по маске подсети:
nmap -sn 192.168.1.0/24
Эта команда просканирует все 256 адресов в подсети 192.168.1 без сканирования портов, вернет список текущих активных устройств с их именами и ip-адресами.
Вот так можно получить список всех устройств с открытым 22-м портом (по умолчанию используется для ssh) в той же подсети:
nmap -p 22 --open -sV 192.168.1.0/24
Вместо маски подсети можно использовать диапазон адерсов:
nmap -sn 192.168.1.*
просканирует все 256 адерсов, начинающихся с 192.168.1., а
nmap -sn 192.168.1.24-128
просканирует адреса с 192.168.1.24 по 192.168.1.128.

Sublime Text 3: как запускать скрипты с помощью python3 а не python

По умолчанию в Sublime Text 3 python-скрипты выполняются с помощью команды python. При этом в Ubuntu 14.04 эта команда соответствует python версий 2.х. Чтобы выполнять скрипты в python версии 3.х (с помощью команды python3) необходимо выполнить следующие действия:
Выбираем в меню:  Tools -> Build System -> New Build System
Вводим в открывшемся окне:
{ 
"cmd": ["/absolute_path_to_python_binary/python3", "$file"] 
, "selector": "source.python" 
, "file_regex": "file \"(...*?)\", line ([0-9]+)" 
}
где absolute_path_to_python_binary - абсолютный путь до бинарников python3, который можно получить с помощью команды:
which python3
Затем сохраняем, и в меню Tools -> Build System выбираем схему по имени, под которым мы ее ранее сохранили.

NodeJS: простейший web-сервер принимающий POST-запросы с JSON

Я использую этот простой web-сервер для быстрого тестирования приложений, которые должны отправлять объекты JSON на сервер.
Для начала надо установить NodeJS (если он еще не установлен). В Ubuntu это делается с помощью следующей команды в терминале:
sudo apt-get install nodejs
Затем создаем файл (например, server.js) и помещаем в него следующий код:
var http = require('http');

const PORT=8080; 

function handleRequest(request, response){
    var body = [];
    request.on('error', function(err) {
        console.error(err);
    }).on('data', function(chunk) {
        body.push(chunk);
    }).on('end', function() {
        body = Buffer.concat(body).toString();
        try {
            var jsonObj = JSON.parse(body);
            console.log(jsonObj.var1);
            console.log(jsonObj.var2);
        } catch (e) {
            console.error(e);
        }

        response.on('error', function(err) {
            console.error(err);
        });

        response.writeHead(200);    
        response.end();
    });
}

var server = http.createServer(handleRequest);

server.listen(PORT, function(){
    console.log("Server listening on: http://localhost:%s", PORT);
});
Далее сохраняем файл и запускаем сервер с помощью команды:
nodejs server.js
Сервер будет слушать порт 8080, в случае входящего запроса пытаться интерпретировать его тело как объект JSON (в данном случае, объект с двумя полями: var1 и var2), выводить значение полей в консоль и отправлять обратно HTTP-код 200 (ОК). Если тело запроса не удалось интерпретировать как объект JSON, в консоль будет выведена ошибка (как и в случае, если ошибка произошла при приеме запроса или передаче ответа).
Протестировать работу сервера можно с помощью утилиты curl:
curl -H "Content-Type: application/json" -X POST -d '{"var1":"1","var2":"0"}' 127.0.0.1:8080

Использование умных указателей в C++ в качестве параметров

Этот пост является переводом статьи Герба Саттера: GotW #91 Solution: Smart Pointer Parameters.

Постановка проблемы

Простой вопрос

1. Каковы недостатки с точки зрения производительности следующего объявления функции? Объясните.
void f( shared_ptr<widget> );

Вопросы посложнее

2. Каковы недостатки с точки зрения корректности объявления функции из вопроса 1?

3. Ваш коллега реализует функцию f, которая принимает объект класса widget в качестве обязательного параметра, предназначенного только для чтения, и пытается выбрать из следующих возможных способов передать параметр (опустим ключевое слово const):
void f( widget* );             (a)
void f( widget& );             (b)
void f( unique_ptr<widget> );  (c)
void f( unique_ptr<widget>& ); (d)
void f( shared_ptr<widget> );  (e)
void f( shared_ptr<widget>& ); (f)
Для каких ситуаций какой способ подходит? Объясните свой ответ и укажите в каких случаях и куда конкретно стоит также добавить const к типу параметра. (Есть и другие способы передать параметр, но мы рассмотрим только представленные выше.)

SparkFun ESP8266 Thing: подключение и прошивка в Ubuntu 14.04

Подключение

SparkFun ESP8266 Thing - это плата для разработчиков на основе WiFi модуля ESP8266. К сожалению, на нее невозможно заливать прошивку просто через USB, USB используюется только для обеспечения питанием. Для программирования модуля необходим USB-to-Serial конвертер, например, такой, как использовал я: SparkFun FTDI Basic Breakout. Но и любой другой конвертер с 3,3 В на выходе должен подойти. Чтобы подключить конвертер к плате, нужно на ESP8266 Thing напаять разъем (далее будет фотография того, что получилось у меня).
Также не рекомендуется прошивать ESP8266, когда питание подается по USB. В моем случае это не было проблемой, так как у меня имелась батарейка, купленная специально для использования с этим модулем: JA-803450P. ESP8266 Thing умеет заряжать батарейку, когда подключено питание по USB.

Вывод в Serial Monitor в Arduino IDE

Чтобы получать вывод c серийного порта в Serial Monitor в Arduino IDE необходимо, чтобы до первого вывода один раз в программе был выполнен следующий код:
while(!Serial.available());
где Serial соответствует серийному порту, с которого хотим получить вывод.
При запуске программа на этой строчке войдет в бесконечный цикл - в это время надо открыть Serial Monitor и отправить какой-нибудь символ в порт. После этого выполнение программы продолжится, а аргументы команды
Serial.print();
будут печататься в окне Serial Monitor.

Ubuntu: Как проиграть Raw PCM аудио файл в командной строке Ubuntu 14.04

Чтобы проиграть аудио файл представляющий из себя сырые PCM данные (без заголовка) можно, например, воспользоваться командой:
mplayer -rawaudio samplesize=2:channels=2:rate=44100 -demuxer rawaudio test.raw
Она проиграет PCM стерео файл, по 2 байта на сэмпл, с частотой сэмплов 44100 Hz.
Ну а если не нужно играть в терминале, можно просто воспользоваться Audacity.