Решения тех проблем, с которым мне приходилось сталкиваться.

Показаны сообщения с ярлыком утилиты. Показать все сообщения
Показаны сообщения с ярлыком утилиты. Показать все сообщения

среда, 28 декабря 2011 г.

удаление лишних пробелов в конце строки

Задача из области написания кода. Часто случается так, что в конце строки образуются лишние пробелы. Как их быстрее всего увидеть и удалить? Приходит на помощь sed.

На первый взгляд, задача тривиальна:

sed -ri 's/\s+$//g' foobar


Но есть в ней одна засада. Если исходный файл foobar имеет переводы строк системы DOS/Windows (т.е. два символа CR-LF), то символ \r в unix системах будет трактован тоже как пробел и соответственно удален. В итоге вместе с пробелами поменяются и переводы строк. Что может быть нежалательно.

Правильнее будет сделать так:
sed -ri 's/ +(\r)?$/\1/g' foobar


В данном случае мы запоминаем, был ли в конце строки символ \r и заменяем последовательность пробелов (именно пробелов, а не вообще пробельных символов) на этот символ (или его отсутствие, если исходный файл с переводами *nix).

Ну и еще пара моментов. Флаг -r, расширенные регулярные выражения, просто чтобы не писать лишние бэкслеши. Флаг -i замена файла in-place, т.е. и поток будет прочитан из файла и записан в него же.

Ну и наконец команда, чтобы выполнить данную операцию для всех файлов директории.
find . -name '*.java' -exec sed -ri 's/ +(\r)?$/\1/g' \{\} \;

четверг, 14 июля 2011 г.

"Пул" процессов в bash

Интересный способ имитации пула процессов найден с помощью команды xargs.

Известно, что эта команда может выполнить некую процедуру для каждого элемента из входного списка (stdin). Оказывается, она способна выполнять процедуру не последовательно для каждого элемента, а поддерживать выполнение заданного количество копий. Т.е. если на входе у нас 1 2 3 4 5 6 7 8 9 10 и мы хотим одновременное выполнение 4 процессов, то xargs сразу же запустит 4 процесса для 1 2 3 4 и как только кто-то из них завершит выполнение запустит новый уже с аргументом 5 и так далее.

Очень удобно, на самом деле, в некоторых случая. В общем, все просто - опция --max-procs.

пятница, 29 октября 2010 г.

Звук по завершении долгой консольной команды

Допустим, нужно выполнить в терминале команду, которая выполняется достаточно долго, чтобы ее дожидаться ничем больше не занимаясь. В тоже время, бывает такая потребность, что как только команда выполнится нужно сделать какое-то следующее действие. Ну и вообще, просто чтобы не забыть, что она вообще там выполняется.
Придумано такое решение. Можно в командной строке указать, что после требуемой команды выполнить еще одну, которая ... подаст звуковой сигнал!
В простейшем случае воспроизвести звук из терминала можно командой beep. Чтобы не спутать звук, с обычным сигналом bell из терминала, в параметрах beep можно указать длительность и частоту звука. Звук будет воспроизведен через встроенный динамик (pc speaker).
Пример:


do_time_consuming_task; beep -f 1000 -l 500 -r 3


upd В xterm обнаружилась интересная функция. Называется PopupOnBell, в простейшем случае активируется при запуске с ключом -pob. В таком режиме, если на терминал выводится символ ASCII BELL (код 0x07 или 8-ричный 007), то окно терминала уведомляет менеджер о наличии активности (точно не знаю как назвать), после чего Desktop Manager, например, Gnome отображает кнопку такого окна на панели задач мигающей (примерно так, как если свернутый Instant Messanger получает новое сообщение).
Соответственно, можно, например, чтобы каждый раз, как shell в терминале получает управление (выводит приглашение) терминал сообщал о активности.

PS1="\\007$PS1"
sleep 5

Если выполнить эти команды, а потом свернуть окно xterm, то через 5 секунд оно замигает в панели задач.

upd #2 Аналогичное решение для gnome-terminal.

среда, 20 октября 2010 г.

Длинная командная строка через xargs

Иногда приходится выполнить команду с таким количеством аргументов, что '*' (звездочка) уже не работает - shell пытается создать слишком длинную командную строку. Выход - разбить список на несколько более мелких и выполнить команду для каждого из них. В том числе и для этого создана команда xargs.
Она получает список из stdin и выполняет переданную ей команду подставляя список в качестве ее аргументов. Для разбития списка на куски есть разные опции (-n или -s).
Но до сего момента я не подозревал, что список аргументов может быть не в самом конце нужной команды, но и в любом месте.
Для примера. Если нужно скопировать кучу файлов и cp * <dest> не работает. Пробуем писать:

ls * | xargs -n 1000 cp /dest

И оно тоже не будет работать, потому как список аргументов от xargs будет подставлен в конец команды cp и в итоге будет выглядеть примерно как:

cp /dest arg1 arg2 ... argn

Как поместить список аргументов в нужное место? А вот это в man'е не совсем очевидно при первом прочтении. А в итоге нужно делать так:

ls * | xargs -n 1000 -I FILES cp FILES dest

Что тут происходит? Опция -I сообщает xargs, что если подстрока 'FILES' встретится где-либо в части исполняемой команды (initial arguments), то именно в это место и нужно раскрыть список аргументов из stdin.

вторник, 7 июля 2009 г.

Программное перемещение в корзину

Нашел такой пакет - trash. Позволяет управлять корзиной из скриптов. Таким образом настроил автоматическое удаление старых файлов из downloads в корзину.

среда, 3 декабря 2008 г.

Как сделать hex-dump

Иногда бывает нужно заглянуть внутрь файла на уровне hex-dump. Обычно на помощь приходит mc или другие GUI-утилиты (например - ghex).
А то в же время в почти всех *nix дистрибутивах есть простая консольная утилита xxd. По умолчанию она "дампит" входной поток в выходной. Но самое главное ее свойство - она умеет выполнять обратное преобразование. Т.е. генерить из дампа бинарный файл.

PS: когда-то я именно так спасал стертый MBR... :)

суббота, 7 июня 2008 г.

Найти процесс открывший сетевое соединение

Задача: нужно выяснить, что за процесс "висит" на неком известном tcp/udp порту.
Решение: Известно как минимум 3 способа.


  1. lsof с ключом -i. Например:
    lsof -i tcp:80

  2. netstat с ключом -p. Пример:
    netstat -nlp | grep 80


  3. fuser. Пример:
    sudo fuser -v 80/tcp


UPD:Утилиты lsof и fuser можно использовать для тех же целей, но применительно к файлам. Например, чтобы перезагрузить модуль ядра ALSA нужно завершить апплет микшера и может быть другие процессы, которые не всегда очевидны (в данной случае файлом выступает специальное устройство из /dev/snd/*)

среда, 2 апреля 2008 г.

Перечитать таблицу разделов

Делаем, например, так:


blockdev --rereadpt /dev/sda


Зачем это нужно? Чтобы без перезагрузки заставить линукс обновить информацию о разделах из MBR. Это в свою очередь нужно после операций изменения размеров или кол-ва разделов винчестера.

понедельник, 17 марта 2008 г.

"скриншот" из командной строки

Как?
Воспользуйтесь утилитой scrot (SCReen shOT)

понедельник, 25 февраля 2008 г.

Размер всех файлов в директории

Задача: просуммировать размер всех файлов в директории. Первое, что приходит на ум - использовать команду du.


du -hs

Но она показывает размер, занимаемый файлами (и под-директориями!) на диске. А часто нужно посчитать именно кол-во байтов во всех файлах. Тогда можно сделать так:

find . -type f -exec ls -l \{\} \; | awk '{s+=$5} END {print s}'

Так как find весьма мощная утилита, то изменяя ее параметры можно подсчитать суммарный объем данных в файлах, удовлетворяющих заданным условиям.

Как правильно подсказали в комментариях, есть еще более короткое и правильное решение:

find . -type f -printf '%s\n' | awk '{SUM+=$1} END {print SUM}'

пятница, 8 февраля 2008 г.

информация об оборудовании

Потребовалось узнать, в каких слотах памяти какие планки стоят (на работающей машине, естественно). По этому поводу была обнаружена архи-полезная утилита lshw.
Не на всех системах степень детализации информации одинаковая, это понятно, но на более новых все видно.
Tip: с ключом -html программа генерит отчет в соответствующем формате, после чего его можно комфортно изучить в любимом браузере.

Для тех кто не знал - из той же серии есть еще 2 утилиты:
lsusb - информация о устройствах подключенных к шине USB;
lspci - тоже самое для PCI.

А еще есть утилита hwinfo, но с данной конкретной задачей она не справилась. Просто показал сколько всего памяти и все. Зато она выводит много всякого другого.

вторник, 22 января 2008 г.

Управление параметрами Ethernet-карты

Как посмотреть режим работы сетевой карты и/или изменить его? (Имеется ввиду такие параметры, как скорость - 10/100/1000, дуплекс - Full/Half и прочее). Существует утилита ethtool в одноименном пакете. В ubuntu ставится по-умолчанию.
Просмотр параметров:


sudo ethtool eth0

четверг, 10 января 2008 г.

добавление локали в ubuntu

Иногда требуется использовать одну или несколько дополнительных локалей (например, ru_RU.KOI8-R, ru_RU.CP1251). Как добавить? В новых версиях ubuntu процедура немного отличается от старых. Все поддерживаемые локали находятся в файлах, расположенных в каталоге /var/lib/locales/supported.d/
В частности там есть файл local. Добавляем строчки с названиями нужных локалей.


ru_RU.CP1251 CP1251
ru_RU.KOI8-R KOI8-R

А потом выполняем команду locale-gen

понедельник, 12 ноября 2007 г.

сравнить две директории

Иногда хочется узнать, какие файлы есть в одной директории, но которых нет в другой (или наоборот). Самой простой способ - команда diff


diff -q dir1 dir2

Если хочется программной обработки, то можно вот таким способом (показывает какие из файлов в dir1 отсутствуют в dir2):

for i in dir1/*; do
if [ -f $i -and \( ! -e dir2/`basename $i` \) ]; then
# do something
echo $i
fi;
done

четверг, 1 ноября 2007 г.

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

Вопрос: Как вырезать строки с номерами с x по y из текстового файла? Например, есть файл:


1
2
3
4
5

Хочется получить

3
4

Ответ: как всегда на помощь приходит sed

sed -n '3,4p' test.txt

суббота, 27 октября 2007 г.

запуск и останов сервисов (служб)

В redhat-подобных системах есть полезная команда service, которая по сути позволяется не писать /etc/init.d/. В debian и деривиатах для этого есть invoke-rc.d. Команада имеет и ряд дополнительных параметров, например, --quiet (не выводить на экран сообщений об ошибках).

переименовать группу файлов

Предыстория. Чтобы читать электронные книжки на портативном устройстве я распаковываю chm в html (пакет libchm-dev, команда extract_chmLib). Часто получаемые HTML файлы имеют извращенческий префикс в имени, вида _12345ABCDE_toc.html. Меня это не устраивает и поэтому перед копированием в КПК я делаю так:


rename 's/_12345ABCDE_//g' *.html
А потом и меняю ссылки внутри файлов:

sed -i 's/_12345ABCDE_//g' *.html
UPD: Увидел на одной сайте целый скрипт на шелле, выполняющий единственную функцию - преобразующий имена всех файлов текущей директории в нижний регистр. Я подумал, что наверняка rename это уже умеет. Я оказался прав - вот решение:

rename 'y/[A-Z]/[a-z]/' *
Юзается команда "трансляции" (y), которую в том числе поддерживает и sed.

четверг, 28 июня 2007 г.

перекодировка текста

До сих пор часто требуется перекодировать файл из одной кодировки в другую. Например, если он попал на машину с системы Windows, для которой родной 8-битной является Windows-1251.
До сего дня не знал, что в большинстве nix-систем есть маленькая программка iconv, которая перекодирует стандартный поток ввода и направляет результат в стандартный поток вывода.
Формат использования самоочевидно прост:


iconv -f <from_encoding> -t <to_encoding>

Также можно посмотреть список поддерживаемых кодировок:

iconv -l

Сама функция iconv предоставляется glibc, так что действительно программа вездесуща.

вторник, 19 июня 2007 г.

заменить текст в группе файлов

Для тех из вас, кто достаточно искушен в стандартных утилитах unix есть такой совет:


find *.py -print0 | xargs sed -i 's/old/new/g'

В данном простом случае можно обойтись и без find:

sed -i 's/old/new/g' *.py

понедельник, 30 апреля 2007 г.

ZIP и интернациональные символы в именах файлов архива

Программа zip не очень правильно работает с национальными символами в именах файлов. Чтобы потом распаковать архив, созданный, например, под Windows, нужно сделать следующее:


unzip <archive>
convmv -f iso8859-1 -t cp850 -r --notest --nosmart <arch_dir>
convmv -f cp866 -t utf8 -r --notest --nosmart <arch_dir>

Это при условии, что локаль utf8. Если koi8-r, то в последней команде это нужно отразить.

Собственно основную работу выполняет утилитка convmv, предназначенная для преобразования кодировок в именах файлов. Находится она в одноименном пакете.