bash-скриптинг: как найти абсолютный путь к символической ссылке / ..? - PullRequest
8 голосов
/ 07 июня 2011

Дано два файла:

generic/scripts/hello.sh
parent/scripts -> generic/scripts

После вызова parent/scripts/hello.sh из любого места, я хотел бы (в скрипте) найти полный путь к родительскому каталогу. В этом случае parent.

Основная проблема заключается в том, что parent/scripts/.. относится к generic в Unix. С другой стороны, все, что связано с регулярными выражениями, не является общим и может быть подвержено ошибкам.

Решения, которые не работают:

`dirname $0`/..
realpath  `dirname $0`/..
readlink -f `dirname $0`/..
`cd *something*/..; pwd`
`perl ... abs_path(...)`

Все это будет указывать на generic, а не parent из-за символической ссылки.

Все, что включает в себя регулярные выражения, не может быть адаптировано / универсально, может не работать для более сложных путей. В пути могут быть и другие .. и символические ссылки, вам нужен прародитель, это имя каталога, включающее .., вы вызываете его через $ PATH ...

Более того, я бы хотел, чтобы он работал в любом случае, даже если он вызывается через $PATH.

Любое простое безопасное решение этой простой проблемы? Я имею в виду, что он просто получает родительский каталог!

Что я использовал:

dir=$( dirname $( cd `dirname $0` >/dev/null; pwd ) )

Не знаю, если он идеален, но, похоже, ведет себя как ожидалось.

Ответы [ 6 ]

5 голосов
/ 07 июня 2011

Попробуйте это:

basename $(dirname $(dirname $0))

или, возможно, просто

$(dirname $(dirname $0))

Неясно, хотите ли вы parent в одиночку или полный путь.

1 голос
/ 06 марта 2013
pushd $(dirname $0)
FOO=$(pwd)
popd

Это дает вам абсолютный путь к каталогу, в котором выполняется скрипт.

1 голос
/ 07 июня 2011

Я бы порекомендовал 1) использовать pwd -P, который всегда даст вам физический путь, а затем перейти с относительным путем к другой точке Это наиболее безопасно.

2) использовать pwd -L

0 голосов
/ 16 июля 2015

в bash вы можете выполнить некоторые манипуляции со строками на $PWD, если эта переменная доступна.

Для пути к родительскому каталогу используйте:

${PWD%/*}

Другие примеры:

me@host:/tmp/bash_string/ma ni-pu_la/tion$ echo -e \
"\$PWD or \${PWD} : " $PWD \
"\n\${PWD##/*}     : " ${PWD##/*} \
"\n\${PWD##*/}     : " ${PWD##*/} \
"\n\${PWD#/*}      : " ${PWD#/*} \
"\n\${PWD#*/}      : " ${PWD#*/} \
"\n\${PWD%%/*}     : " ${PWD%%/*} \
"\n\${PWD%%*/}     : " ${PWD%%*/} \
"\n\${PWD%/*}      : " ${PWD%/*} \
"\n\${PWD%*/}      : " ${PWD%*/} \
"\n" # Gives :
$PWD or ${PWD} :  /tmp/bash_string/ma ni-pu_la/tion 
${PWD##/*}     :  
${PWD##*/}     :  tion 
${PWD#/*}      :  tmp/bash_string/ma ni-pu_la/tion 
${PWD#*/}      :  tmp/bash_string/ma ni-pu_la/tion 
${PWD%%/*}     :  
${PWD%%*/}     :  /tmp/bash_string/ma ni-pu_la/tion 
${PWD%/*}      :  /tmp/bash_string/ma ni-pu_la 
${PWD%*/}      :  /tmp/bash_string/ma ni-pu_la/tion
0 голосов
/ 06 января 2014

Я называю свой скипт так: ../script1, и он имеет относительный вызов ../relative/script2

`(cd $0/.. && pwd)`/relative/script2

в script1

0 голосов
/ 07 июня 2011

Что по этому поводу:

echo `cd .. && pwd`
...