Например, проверьте, $PWD
является ли подкаталог / home. Другими словами, я ищу операцию строки bash, чтобы проверить, начинается ли одна строка с другой.
Например, проверьте, $PWD
является ли подкаталог / home. Другими словами, я ищу операцию строки bash, чтобы проверить, начинается ли одна строка с другой.
Ответы:
Если вы хотите надежно проверить, является ли каталог подкаталогом другого, вам потребуется нечто большее, чем просто проверка префикса строки. Ответ Жиля подробно описывает, как правильно выполнить этот тест.
Но если вам нужна простая проверка префикса строки (может быть, вы уже нормализовали свои пути?), Это хорошо:
test "${PWD##/home/}" != "${PWD}"
Если $PWD
начинается с "/ home /", он удаляется с левой стороны, что означает, что он не будет совпадать с правой стороной, поэтому "! =" Возвращает true.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
для определения, находится ли пользователь в данный момент subdir
или в подкаталоге subdir
, так как %% записывает с конца строки вместо начала. Это должно быть полезно всем, кто ищет дополнительную информацию о замене параметров: tldp.org/LDP/abs/html/parameter-substitution.html
Чтобы проверить, является ли строка префиксом другой, в любой оболочке стиля Борна:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
Тот же принцип работает для проверки суффикса или подстроки. Обратите внимание, что в case
конструкциях, в отличие от имен файлов, *
совпадает любой символ, включая /
или начальный .
.
В оболочках, которые реализуют [[ … ]]
синтаксис (т. Е. Bash, ksh и zsh), его можно использовать для сопоставления строки с шаблоном. (Обратите внимание, что [
команда может только проверять строки на равенство.)
if [[ $PWD/ = /home/* ]]; then …
Если вы специально проверяете, находится ли текущий каталог под ним /home
, простого теста подстроки недостаточно из-за символических ссылок.
Если /home
это отдельная файловая система, проверьте, находится ли текущий каталог ( .
) в этой файловой системе.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Если у вас есть NetBSD, OpenBSD или GNU (то есть Linux) readlink
, вы можете использовать readlink -f
для удаления символических ссылок из пути.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
В противном случае вы можете использовать, pwd
чтобы показать текущий каталог. Но вы должны позаботиться о том, чтобы не использовать встроенную оболочку, если ваша оболочка отслеживает cd
команды и сохраняет имя, которое вы использовали для доступа к каталогу, а не его «фактическое» местоположение.
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Сырая версия:
[ ${PWD:0:6} = "/home/" ]
Недостаток в том, что сначала нужно считать символы, и нельзя заменить /home/
чем-то общим $1
.
редактировать (спасибо @Michael) за обобщение для сравнения $VAR
можно использовать
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
это длина $var
, так что вы можете обобщить это как[ "${PWD:0:${#1}}" = "$1" ]
Я не очень хорошо понимаю вопрос, но чтобы найти родителя $ PWD , сделайте dirname $PWD
. Чтобы найти родителя родителя, запустите dirname $(dirname $PWD)
и так далее ...
/
. Хорошо, я могу проверить рекурсивно, но разве нет ничего проще?
Использование awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
Хм, жаль, что [
нет возможности проверить STRING1 starts with STRING2
условие.
Вы можете попробовать echo $PWD | grep '^$VAR'
, но он может потерпеть неудачу интересными способами, когда VAR
содержит специальные символы.
awk
«S index
функция должна быть в состоянии сделать трюк. Но все это кажется слишком тяжелым для такой легкой вещи, чтобы проверить.
Если найденная часть пути найдена, я «очищаю» переменную:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
И если бы это был [code-golf] ( stackoverflow.com/questions/tagged/code-golf)question, вы бы меня избили двумя символами ;-) Также это выглядит более читабельно ...