21 апреля 2011 г.

Как узнать полный путь до запущенного bash-скрипта

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

Можно, конечно, поступить просто и в самом скрипте в переменной жёстко прописать полный путь до каталога, в котором этот скрипт лежит. Получится что-то вроде этого:
#!/bin/bash

DIRECTORY="/home/user/my_scripts"
cd $DIRECTORY

# запуск "соседних" скриптов
./script1.sh
./script2.sh
Вполне рабочий вариант и две обозначенные выше проблемы будут решены, но если надо будет переместить скрипт в другой каталог, то и значение переменной придётся руками поменять в самом скрипте. Не очень удобно.

Для красивого решения проблемы нужно знать всего три вещи:
  1. Путь до выполняющегося скрипта можно узнать с помощью $0, но проблема в том, что он относительный, т.е. если вы запустите скрипт как ./script.sh, то и $0 будет содержать ./script.sh
  2. Команда readlink с параметром -e решит сразу две проблемы: во-первых она вернет полный путь до файла скрипта, если вы воспользовались для запуска символической ссылкой (даже если это была цепочка симлинков), а во-вторых преобразует относительный путь, если такой получен с помощью $0, в абсолютный
  3. Чтобы избавиться от имени файла скрипта в конце абсолютного пути, нужно воспользоваться командой dirname
    Пример:
    #!/bin/bash
    
    # полный путь до скрипта
    ABSOLUTE_FILENAME=`readlink -e "$0"`
    # каталог в котором лежит скрипт
    DIRECTORY=`dirname "$ABSOLUTE_FILENAME"`
    
    # запуск "соседних" скриптов
    $DIRECTORY/script1.sh
    $DIRECTORY/script2.sh
    

    4 апреля 2011 г.

    Прикручиваем кнопки "Поделиться" от Яндекса к www.blogger.com

    Захотелось мне прикрутить к блогу эти самые кнопочки. Напишу пару слов о том, как я это сделал.

    Сначала идём по адресу http://api.yandex.ru/share/, настраиваем вид блока "Поделиться" и выбираем сервисы, в которые хочется постить с его помощью. Получаем код, вроде этого:

    Теперь заходим в Панель инструментов -> Дизайн -> Изменить HTML. Ставим галку рядом с "Расширить шаблоны виджета".

    Между тегами <head> и </head> где-нибудь втыкаем первую строку из листинга выше. Короче эту:

    Дальше надо выбрать место, где хочется разместить эти кнопки. Я решил вставить их под сообщением, ниже автора и времени создания сообщения. Если вас устраивает это место, то ищите в шаблоне строку <span class="post-icons"> и над ней вставляйте оставшуюся часть полученного кода:

    Если вы сохраните шаблон и зайдёте на блог, то кнопочки должны будут появиться и будут даже работать, только не всегда правильно. Например, если отдельно открыть страницу с конкретным сообщением блога и там нажать на какую-либо из кнопок "поделиться", то всё отработает правильно. А вот если нажать на одну из этих кнопок под каким-либо сообщением на главной странице, то делёжка будет осуществляться не ссылкой на это сообщение, а ссылкой на главную страницу блога. Для того, чтобы такого безобразия не происходило, нужно элементу DIV добавить атрибуты data-yashareLink и data-yashareTitle, которые позволяют установить ссылку, которой нужно поделиться и заголовок сообщения, соответственно. Но для того, чтобы динамически получать ссылку и заголовок нужно использовать хитрые выражения, которые понимает движок блоггера.

    Вот как это выглядит:

    В процессе генерации страниц блога выражение expr:data-yashareLink='data:post.url' будет заменено блоггером на data-yashareLink='http://myblog.blogspot.com/путь_до_сообщения', а expr:yashareTitle='data:post.title' на yashareTitle='Заголовок_сообщения'.

    Кстати, контейнером для кнопок может быть не обязательно элемент DIV, я использую SPAN. Вот код, который я добавил себе в шаблон: