Должны ли скрипты оболочки работать с абсолютными или относительными путями?

Должны ли скрипты оболочки работать с абсолютными или относительными путями?

Я в процессе преобразования некоторых пакетных скриптов в скрипты оболочки. Пакетные скрипты имеют команды cd, но по-прежнему используют абсолютные пути.

foo.bat:

pushd
cd C:\some\directory
copy C:\some\directory\foo.txt C:\some\other\directory
popd

Я считаю, что cd в этом скрипте излишен, так как копируемый файл вызывается с использованием абсолютных путей. Мне нужно преобразовать это в скрипт оболочки. У меня есть два варианта:

test1.sh:

cp /some/directory/foo.txt /some/other/directory

test2.sh:

cd /some/directory
cp foo.txt /some/other/directory

В первом случае используется только cp с абсолютными путями, а во втором — cd и относительные пути.

Мой вопрос: какой из этих двух примеров является лучшей практикой с точки зрения использования путей в скриптах оболочки?

В качестве дополнительного вопроса: нужен ли pushd/popd в каком-либо из этих примеров?

решение1

cdВызов скрипта не обязательно плох , но делать это следует умеренно. Множественные вызовы — cdэто «запах кода». Абсолютные пути обычно предпочтительнее.

cdможет потерпеть неудачу. Обязательно обрабатывайте ошибки правильно.

После вызова cdотносительные пути становятся недействительными. В частности, если вы пишете скрипт-оболочку, который подготавливает что-то, а затем запускает другую команду, никогда не вызывайте cd: пользователь может рассчитывать на то, что команда будет запущена в исходном каталоге. Если ваш скрипт использует имена файлов, переданные в командной строке, они обычно являются относительными к исходному каталогу; вы можете добавить "$PWD/"их в начало, чтобы сделать их абсолютными, но это приведет к плохим сообщениям об ошибках, если что-то пойдет не так.

Переменная PWDвсегда содержит текущий каталог, поэтому вы можете сохранить его в другой переменной и вернуться назад, вызвав cdпозже. Однако имейте в виду, что это может не сработать в некоторых крайних случаях, например, если скрипт запущен с низкими привилегиями и ему не разрешено вернуться в исходный каталог, или каталог перемещается во время работы скрипта.

Будьте осторожны с относительными путями: они могут начинаться с -, а аргументы команд, начинающиеся с , -интерпретируются как опции, если вы не примете меры предосторожности. Абсолютные пути не имеют этой проблемы.

решение2

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

  • абсолютные пути более понятны: тот, кто будет поддерживать/изменять ваш скрипт (вы или другие), сможет каждый раз знать, какие каталоги задействованы;
  • при использовании абсолютных путей вы уверены, что задействованные каталоги — это те, путь к которым вы прописали в скрипте;
  • Относительные пути короче, но вам нужно быть уверенным в поддереве, с которым вы работаете;
  • можно добиться краткости, заменив повторяющиеся пути переменной в начале скрипта (например, /var/log/app/component/module/logfile.log -> $module_log_dir/logfile.log)

Как заметил thrig, можно добавить проверку задействованных каталогов непосредственно перед выполнением команды.

Связанный контент