Наприклад, перевірте, чи $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)запитання, ти би побив мене двома знаками ;-) Також це виглядає читабельніше ...