Bash: где лежит мой скрипт ?

Как правило скрипт используется для автоматизации обработки каких либо других файлов. Я, зачастую, использую скрипты для автоматизации сборки, настройки окружение и генерации каких-либо отчетов. Собственно самая первая задача - это найти, а где находятся все эти файлы процесс обработки, которых необходимо автоматизировать.

Как правило необходимые файлы были скопированы вместе со скриптом и относительные пути известны, но вот где лежит сам скрипт пока не известно. Собственно задача решается тривиально:

SCRIPT_PATH=`dirname $0`

Переменная $0 содержит путь и имя скрипта относительно текущего каталога пользователя. Если пользователь выполняет команду bash project/yourscript.sh находясь в директории /tmp, то эта переменная будет содержать project/yourscript.sh и чтобы получить полный путь необходимо выполнить следующее:

cd $SCRIPT_PATH
ABS_SCRIPT_PATH=$PWD
cd -

Мы переходим в относительный каталог скрипта и выполняем команду pwd и возвращаемся обратно в текущий каталог. К сожалению, нет ( или я плохо искал ) встроенных команд в bash который бы проверял абсолютный путь задал пользователь или нет, а иначе если пользователь попытался выполнить скрипт путем bash /tmp/project/your_script.sh находясь в каталоге /root, то склеиванием мы получаем несуразное /root/tmp/project/your_script.sh. Вот и приходится реально переходит в каталог и возвращаться обратно с помощью cd -.

Конечно есть вероятность, что пользователь выполнит, нечто вроде:

cat project/yourscript.sh | bash

Но от этого никто не застрахован, по крайне мере, тем более выполнить bash скрипт можно и более извращенными методами :). Единственное, что можно в вышеупомянутой ситуации сделать - выявить эту ситуации и вывести сообщение об ошибке. При интерпретации скрипта через стандартный ввод, $0 будет содержать слово bash. Однако думаю что полагаться на это не стоит, гораздо надежнее проверить действительно ли по этому пути находится скрипт:

if [ ! -f $0 ]; then
  echo "Error: Please run bash <script.sh>"
  exit 2
fi

Код проверяет нахождения файла по этому пути, теперь осталось только проверить что это наш скрипт, сделать это можно положив во вторую строчку уникальное значение:

#!/bin/bash
# Your script name or uniq id

# Cheks if file exists
if [ ! -f $0 ]; then
  echo "Error: Please run bash <script.sh>"
  exit 2
fi

SECOND_LINE=`tail -n +2 $0 | head -n 1`
# Checks if it's our file
if [ "$SECOND_LINE" != "# Your script name or uniq id" ]; then
  echo "It's not your script path"
  exit 2
fi

echo "Success"

Возможно проверить второе условие, если перейти в папку /bin или создать файл bash в текущей директории, а после этого выполнить команду:

cat project/yourscript.sh | bash

Вот и все, мы получили абсолютный путь до скрипта и сделали защиту от "неправильного" использование, теперь остается только найти нужные файлы, с помощью простого изменения текущего каталога. Лично я использую команды pushd и popd хождения по относительным путям.

Информацию по параметрам выражения if можно посмотреть в Introduction to if