Home » Относительный сценарий оболочки включает в себя Realpath во FreeBSD.

Относительный сценарий оболочки включает в себя Realpath во FreeBSD.

Опубликовано 2 декабря 2023 г.

Обсуждать:
Форум FreeBSD
|
Реддит

Посмотреть эту статью файлы примеров


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

  1. . relative/script.sh зависит от директории вызова.
  2. Символическая ссылка на команду приводит к несогласованному имени и местоположению команды.
  3. Почти все интернет-обсуждения сценариев оболочки посвящены Bash, тогда как я использую sh(1) на FreeBSD (также известной как оболочка Bourne).

доктор: Решение

Использовать $(dirname $(realpath $0)) в ваших командных файлах. realpath(1)

Проблема 1: директория вызова имеет значение

(файлы примеров)

Очевидный способ включения относительных файлов: . relative/script.sh. Имеем следующую файловую структуру:

.
├── bin
│   └── hello.sh
└── lib
    └── libhello.sh

бин/hello.sh:

#!/bin/sh
. lib/libhello.sh

hello

lib/libhello.sh:

hello() {
    echo hello, world
}

Бег ./bin/hello.sh работает так, как ожидалось, тогда как cd bin && ./hello.sh терпит неудачу:

./bin/hello.sh
hello, world
cd bin && ./hello.sh
.: cannot open lib/libhello.sh: No such file or directory

Нам нужен какой-то способ поиска относительно пути к сценарию, а не каталога вызова.

Наивное решение: использовать $0 чтобы найти местоположение сценария

(файлы примеров)

$0 возвращает имя вызванной команды, включая любой префикс каталога. Мы можем использовать его для запроса относительных файлов:

бин/hello.sh:

#!/bin/sh
LIB=$(dirname $0)/../lib
. $LIB/libhello.sh

hello

Теперь команда выполняется успешно, независимо от того, из какого каталога мы ее вызываем:

./bin/hello.sh
hello, world
cd bin && ./hello.sh
hello, world

Однако, $0 — это имя команды, передаваемой в оболочку, которое может не быть реальным командным файлом при использовании символических ссылок.

Проблема 2. Символические ссылки делают имя сценария ненадежным.

(файлы примеров)

Ссылки $0 работает, пока мы не создадим символическую ссылку на файл. Это новая файловая структура:

.
├── actual-hello
│   ├── actual-hello.sh
│   └── libhello.sh
└── bin
    └── hello.sh -> ../actual-hello/actual-hello.sh

Сейчас работает ./bin/hello.sh пытается включить файл относительно bin/hello.shкогда это должно быть относительно actual-hello/actual-hello.sh.

К счастью, FreeBSD дает нам realpath(1) чтобы идентифицировать реальный файл, на который ссылается символическая ссылка.

Read more:  Режиссер-анималист Андреас Килинг: нападение медведя во время съемок

Решение: использовать realpath(1) исходный код относительно реального файла

(файлы примеров)

актуальный-привет/актуальный-привет.sh:

#!/bin/sh
LIB=$(dirname $(realpath $0))
. $LIB/libhello.sh

hello

$(realpath $0) возвращает путь к реальному файлу, поэтому теперь мы можем использовать источник относительно него. Наша символическая ссылка работает независимо от каталога вызова:

./bin/hello.sh
hello, world
cd bin && ./hello.sh
hello, world

Бонусное решение: вспомогательная функция lib.

(файлы примеров)

Теперь, когда мы знаем основную технику, мы можем определить BASE var и напишем нашу библиотеку оболочки относительно нее. Вот структура файла:

.
├── actual-hello
│   ├── bin
│   │   └── actual-hello.sh
│   └── lib
│       ├── libhello.sh
│       └── libhelper.sh
└── bin
    └── hello.sh -> ../actual-hello/bin/actual-hello.sh

актуальный-привет/bin/actual-hello.sh:

#!/bin/sh
BASE=$(dirname $(realpath $0))/..
. $BASE/lib/libhelper.sh
require_lib "hello"

hello

актуальный-привет/lib/libhelper.sh:

: ${BASE:?}
LIB=$BASE/lib

require_lib() {
    . $LIB/lib${1}.sh
}

Заключение

Можно написать очень сильно мощный инструменты используя сценарии оболочки и модульизируйте свой код. Оболочка Bourne не предоставляет четкого механизма ссылки на относительные файлы. Установив базовый каталог командного файла, вы можете надежно ссылаться на соответствующие сценарии оболочки.

2023-12-04 05:21:09


1701675208
#Относительный #сценарий #оболочки #включает #себя #Realpath #во #FreeBSD

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.