Наприклад, перевірте, чи $PWD
це підкаталог / home. Іншими словами, я шукаю операцію bash string, щоб перевірити, чи починається одна рядок з іншої.
Наприклад, перевірте, чи $PWD
це підкаталог / home. Іншими словами, я шукаю операцію bash string, щоб перевірити, чи починається одна рядок з іншої.
Відповіді:
Якщо ви хочете надійно перевірити, чи каталог є підкаталогом іншого, вам знадобиться більше, ніж просто перевірка строкових префіксів. Відповідь Жиля докладно описує, як правильно зробити цей тест.
Але якщо ви хочете просту перевірку префікса рядка (можливо, ви вже нормалізували свої шляхи?), Це хороший варіант:
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
конструкціях, на відміну від імен файлів, *
відповідає будь-якому символу, включаючи a /
або початковий .
.
У оболонках, які реалізують [[ … ]]
синтаксис (тобто 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
Робоча index
функція повинна вміти робити трюк. Але все це здається занадто важким для такої легкої перевірки.
Якщо знайдена шукана частина шляху, я "порожню" змінну:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
І якби це був [код-гольф] ( stackoverflow.com/questions/tagged/code-golf)запитання, ти би побив мене двома знаками ;-) Також це виглядає читабельніше ...