Мне пришлось написать bash-скрипт , чтобы сделать это надежно (и, конечно же, без проверки существования файла ).
Использование
relpath
Возвращает относительный исходный путь.
пример:
#/a/b/c/d/e -> /a/b/CC/DD/EE -> ../../CC/DD/EE
relpath /a/b/c/d/e /a/b/CC/DD/EE
#./a/b/c/d/e -> ./a/b/CC/DD/EE -> ../../CC/DD/EE
relpath./a/b/c/d/e ./a/b/CC/DD/EE
оба получают../../CC/DD/EE
Чтобы провести быстрый тест, вы можете запустить
curl -sL https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath | bash -s -- --test
результат :список тестов
/a -> / -> .
/a/b -> / -> ..
/a/b -> /a -> .
/a/b/c -> /a -> ..
/a/b/c -> /a/b -> .
/a/b/c -> /a/b/CC -> CC
/a/b/c/d/e -> /a -> ../../..
/a/b/c/d/e -> /a/b -> ../..
/a/b/c/d/e -> /a/b/CC -> ../../CC
/a/b/c/d/e -> /a/b/CC/DD/EE -> ../../CC/DD/EE
./a -> ./ -> .
./a/b -> ./ -> ..
./a/b -> ./a -> .
./a/b/c -> ./a -> ..
./a/b/c -> ./a/b -> .
./a/b/c -> ./a/b/CC -> CC
./a/b/c/d/e -> ./a -> ../../..
./a/b/c/d/e -> ./a/b/CC -> ../../CC
./a/b/c/d/e -> ./a/b/CC/DD/EE -> ../../CC/DD/EE
/a -> /x -> x
/a/b -> /x -> ../x
/a/b/c -> /x -> ../../x
/a -> /x/y -> x/y
/a/b -> /x/y -> ../x/y
/a/b/c -> /x/y -> ../../x/y
/x -> /a -> a
/x -> /a/b -> a/b
/x -> /a/b/c -> a/b/c
/x/y -> /a -> ../a
/x/y -> /a/b -> ../a/b
/x/y -> /a/b/c -> ../a/b/c
./a a/b/c/d/e -> ./a a/b/CC/DD/EE -> ../../CC/DD/EE
/x x/y y -> /a a/b b/c c -> ../a a/b b/c c
Кстати, если вы хотите использовать этот скрипт, не сохраняя его, и вы доверяете этому скрипту, то у вас есть два способа сделать это с помощью трюка с bash.
Импортируйте relpath
как функцию bash с помощью следующей команды. (Требуется bash 4+)
source <(curl -sSL https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath)
или вызовите скрипт на --fly, как с комбо curl bash.
curl -sSL https://github.com/jjqq2013/bash-scripts/raw/master/common/relpath | bash -s -- /a/b/c/d/e /a/b/CC/DD/EE
Возможны два решения:
/full/path/here
к вашей переменной $PATH
. или,
$PATH
например sudo ln -s /full/path/here/grabber /usr/bin/grabber
.