bash


romy4 аватар

Как не забыть сделать что-то важное, когда есть много точек выхода из скрипта

Допустим, у вас есть большой скрипт, у которого более, чем одна точка выхода и в этом скрипте вы создаёте кучу временных файлов.

#!/bin/bash
 
declare -a tmp_files
 
pre_exit() {
   rm -f ${tmp_files[1]}
   rm -f ${tmp_files[2]}
   ...
}
 
do_stuff
[ $? -gt 0 ] && pre_exit && exit 1
 
sed
cut
cp
mv
cat
cat
awk { 
..
}
ps auwx | grep
[ $? -gt 0 ] && pre_exit && exit 1
 
other_stuff
 
...
pre_exit

Знакомо, да?

0
Ваша оценка: Ничего
romy4 аватар

Run function under different user

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

#!/bin/bash
 
function run_as_another()
{
  echo "I'm under another user"
  id
}
 
export -f run_as_another
su another -c run_as_another
 
echo Voila!
0
Ваша оценка: Ничего
romy4 аватар

Порядок аргументов для getopts

getopts не будет обрабатывать параметры, если они переданы после аргументов без дефиса
./myscript -a 1 -b 2 hello world
getopts вернёт a и b с параметрами, $OPTIND станет = 4, но
./myscript hello world -a 1 -b 2
работать не будет

rtfm
In fact, getopts will not process arguments without the prefixed -, and will terminate option processing at the first argument encountered lacking them.

getopts != getopt, хотя первое сделано для замены второго

0
Ваша оценка: Ничего
ramok аватар
ramok аватар

Трассировка скриптов

Во время отладки скриптов очень удобно видеть какие трассировку, какие команды исполняются во время исполнения скрипта.
Обычно это реализуется специальными командами включения/выключения трассировки. Информация о выполнении команд обычно выводится в поток ошибок.
Ниже приведены примеры для sh/bash/zsh, expect/tcl, python.

0
Ваша оценка: Ничего

Удаление скрытых каталогов .svn и .git в каталоге с исходным кодом

У меня есть несколько программ, которые я устанавливаю из исходного кода. Это эмуляторы PlayStation 2 - pcsx2 и Nintendo GameCube и Wii - Dolphin. Первый проект использует систему управления версиями SVN, а второй - GIT. Иногда я скачиваю последний SVN/GIT и архивирую его, чтобы потом использовать старую версию при появлении регрессий в эмулируемых играх в новой версии эмулятора. Скрытые каталоги .svn и .git для меня лишние, они используются для обновления старой версии исходного кода. Они могут занимать больше места, чем нужный мне исходный код. Поэтому перед архивированием я их удаляю.

В этом мне помогла найденная в интернете команда. Для SVN:

$ find . -name .svn -print0 | xargs -0 rm -rf

Для GIT:

$ find . -name .git -print0 | xargs -0 rm -rf

или:

$ find . -name .git* -print0 | xargs -0 rm -rf
0
Ваша оценка: Ничего

Меняем имя файла с транслита на кириллицу посредством Bash

Изменить имя файла из транслита в кириллицу.
пример:
ИЗ "AarhAndrejAida.fb2" В "АархАндрейАида.fb2"
находимся в дерриктории изменяемого файла

 
[root@localhost test]# ls       
AarhAndrejAida.fb2

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

echo Aarh_Andrej_Aida.fb2 | while read FILE; do mv "$FILE" $(echo $(basename "$FILE" .fb2) | tr a-zA-Z A-Za-z | iconv -f koi-7).fb2; done

итог:

[root@localhost test]# ls
АархАндрейАида.fb2

если в имени файла существуют разделители:
" _ " или " - " и т.д.
пример:

 
[root@localhost test]# ls
Aarh_Andrej_Aida.fb2

то добовляем:"| tr + символ"
получаем:

echo Aarh_Andrej_Aida.fb2 | while read FILE; do mv "$FILE" $(echo $(basename "$FILE" .fb2) | tr a-zA-Z A-Za-z | iconv -f koi-7 | tr + _).fb2; done

итог:

[root@localhost test]# ls
Аарх_Андрей_Аида.fb2

The end.

0
Ваша оценка: Ничего
ramok аватар

Удалить сломаные символические ссылки

Удалить все сломаные символические ссылки в текущей директории и поддиректориях
bash

find . -type l ! -xtype f ! -xtype d -delete

zsh

rm **/*(-@)
0
Ваша оценка: Ничего
romy4 аватар

Фильтрация stderr без слития с stdout

Сделав два раза swap и между ними grep - мы добиваемся желаемого, фильтруем stderr (почти) без побочных эффектов.

( prog 3>&2 2>&1 1>&3 | grep -v "лишний warning который нельзя отключить" ) 3>&2 2>&1 1>&3

----------------
ликбез:
Когда мы пишем в bash prog X>&Y , то перед запуском происходит присваивание
file_descriptors[X] = file_descriptors[Y]
Присваивания происходят в порядке написания, через них можно сделать swap дескрипторов:

prog 3>&2 2>&1 1>&3
0
Ваша оценка: Ничего
ramok аватар

Путь начинающийся с двойного слеша

Наверное многие замечали "баг" bash/zsh в существовании "двойного root".

$ cd //
$ pwd
//
$ /bin/pwd
/

Это не ошибка, а буквальное следование стандарту POSIX (IEEE Std 1003.1-2001. 4.11 Pathname Resolution ), в котором говорится:

Цитата:

A pathname that begins with two successive slashes may be interpreted in an
implementation-defined manner, although more than two leading slashes shall be
treated as a single slash.

То есть два слеша в начале пути может быть интерпретировано в зависимости от системы. Например в cygwin таким образом можно адресовать windows share. В linux // никакого значения не имеет.

5
Ваша оценка: Ничего Рейтинг: 5 (2 голоса)
ramok аватар

Повторить символ заданное количество раз

Повторить символ заданное количество раз

$ printf 'A%.0s' {1..50}
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ perl -e 'print "A"x50'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ python -c 'print "A"*50'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3.333335
Ваша оценка: Ничего Рейтинг: 3.3 (3 голоса)

Вывод сообщений статуса в bash скрипте

При написании shell скриптов часто возникает необходимость отображать действия скрипта и информацию о то выполнилось действие или нет, чтобы примерно выглядело как выполнение init.d скриптов при загрузке системы.

Примерно вот так:

 * Производится действие 1          [DONE]
 * Производится действие 2          [FAIL]
это ошибка действия 2
4.5
Ваша оценка: Ничего Рейтинг: 4.5 (2 голоса)
angel2s2 аватар

Скрипт для получения информации о домене

Периодически мне бывает нужно получить информацию о каком-либо домене. Для этого я обычно использую utrace и whois. Но это как-то не очень удобно, хотелось все в консольке видеть. Поэтому был набросан однострочник, который выводил инфу с utrace на терминал:

wget -qO- 'http://xml.utrace.de/?query=google.ru' | \
  sed -e '/^<\/\?result\|^<?xml\|^<queries/d;s/<\/.\+>$//g;
     s/^<//g;s/>/\t\t: /g;s/\(^countrycode\|^latitude\|^longitude\)\t/\1/g'

Но все же это не совсем удобно. Вначале запускаю этот однострочник, потом whois, а потом, если вдруг приспичит глянуть, где стоит сервак интересуемого меня домен, то надо лезть на utrace. Не удобно в общем...

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)
ooTync аватар

Генерация *.m3u плейлиста из консоли

Сделал скрипт, генерирующий полноценный M3U-плейлист и выбирающий метаинформацию из тегов файлов. Поддерживаются форматы: mp3, ogg, flac.
Пример работы:

ootync@rtfm:/var/OOTYNC/MP3$ m3u-gen .
#EXTM3U
#EXTINF:311,Manowar — Number 1
Rock/Manowar/1996 - Louder Than Hell/05-Number 1.flac
#EXTINF:249,Manowar — The Power
Rock/Manowar/1996 - Louder Than Hell/10-The Power.flac
...
4.666665
Ваша оценка: Ничего Рейтинг: 4.7 (3 голоса)
angel2s2 аватар

Замер времени выполенения команды

Как раз сейчас понадобилось замерить время работы скрипта... Поискал тут, не нашел :( Зато гугль помог. А все оказалось не просто, а очень просто:

$ time for i in {1..100000} ; do echo $i $>/dev/null ; done
 
real	0m3.680s
user	0m2.964s
sys	0m0.692s

ЗЫЖ В sh этого нету.

3
Ваша оценка: Ничего Рейтинг: 3 (2 голоса)
Vaulter аватар

Распаковка архивов

###   Handy Extract Program
 
extract () {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2) tar xvjf $1   ;;
            *.tar.gz)  tar xvzf $1   ;;
            *.bz2)     bunzip2 $1    ;;
            *.rar)     unrar x $1    ;;
            *.gz)      gunzip $1     ;;
            *.tar)     tar xvf $1    ;;
            *.tbz2)    tar xvjf $1   ;;
            *.tgz)     tar xvzf $1   ;;
            *.zip)     unzip $1      ;;
            *.Z)       uncompress $1 ;;
            *.7z)      7z x $1       ;;
            *)         echo "'$1' cannot be extracted via >extract<" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}

Уже не помню где нашел, не мое :)

Поместить в ~/.bashrc или profile

0
Ваша оценка: Ничего
bliznezz аватар

выход из bash без сохранения истории

перевод типса из shell-fu.

самый простой вариант это SIGKILL своего шелла:

 kill -9 $$

вариант по-нежнее:

 unset SAVEFILE; unset HISTFILE;
0
Ваша оценка: Ничего

Из TIF в PDF и сбор всех PDF в один

Собрал небольшой скриптик для перевода из tif в pdf, а потом сбор всех pdf файлов в один.

Использовал:
http://www.opennet.ru/docs/RUS/bash/bash-1.html
http://flerant.in.nnov.ru/blog/1188235.html
http://www.togaware.com/linux/survivor/Convert_MS_Word.html
http://www.linuxgraphics.ru/forum/viewthread.php?thread_id=566#post_5215

UPD: new version

Линки в тему:

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)

Просмотр ника по ICQ UID на bash

#!/bin/bash
curl http://people.icq.com/people/about_me.php?uin=$1 2> /dev/null | \
    grep "<div class=\"h5-2-new\">" | awk -F ">" '{print $2}'  |\
        iconv -f cp1251 -t utf-8 | awk -F "<" '{print $1}'

UPD:

#!/bin/sh
 
if [ -z "$1" ]; then
    echo Usage: $(basename $0) ICQ-UIN
    exit 1
fi  
 
curl http://people.icq.com/people/about_me.php?uin=$1 2> /dev/null | \
    sed -ne 's,.*<div class="h5-2-new">\([^<]*\)</div>.*,\1,p' | iconv -f cp1251 -t utf-8
0
Ваша оценка: Ничего
ramok аватар

Удобный алиас в zsh для copy/paste примеров из советов

На linsovet.com многие советы содержат примеры запуска команд из командной строки в формате в подобном формате

$ echo команда 1
$ echo команда 2

Этот формат неудобен если вы хотите скопировать сразу несколько команд и скопировать прямо в терминал. Если добавить в ~/.zshrc алиас

alias \$=''

то эта проблема будет решена. Если команда начинается с $, то он будет автоматически убран

Идея взята отсюда

0
Ваша оценка: Ничего