Np. Sprawdź, czy $PWD
jest podkatalogiem / home. Innymi słowy, szukam operacji ciągu bash, aby sprawdzić, czy jeden ciąg zaczyna się od drugiego.
Np. Sprawdź, czy $PWD
jest podkatalogiem / home. Innymi słowy, szukam operacji ciągu bash, aby sprawdzić, czy jeden ciąg zaczyna się od drugiego.
Odpowiedzi:
Jeśli chcesz niezawodnie przetestować, czy katalog jest podkatalogiem innego, potrzebujesz czegoś więcej niż tylko sprawdzania prefiksu łańcucha. Odpowiedź Gillesa szczegółowo opisuje, jak poprawnie wykonać ten test.
Ale jeśli chcesz prostego sprawdzania prefiksu łańcucha (być może już znormalizowałeś swoje ścieżki?), Jest to dobre:
test "${PWD##/home/}" != "${PWD}"
Jeśli $PWD
zaczyna się od „/ home /”, jest usuwany z lewej strony, co oznacza, że nie pasuje do prawej strony, więc „! =” Zwraca true.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
do wykrywania, czy użytkownik znajduje się obecnie w subdir
lub w podkatalogu subdir
, ponieważ %% przechwytuje od końca ciągu zamiast od początku. Powinno to być przydatne dla każdego, kto szuka więcej informacji na temat podstawiania parametrów: tldp.org/LDP/abs/html/parameter-substitution.html
Aby sprawdzić, czy ciąg znaków jest prefiksem innego, w dowolnej powłoce w stylu Bourne'a:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
Ta sama zasada działa w przypadku testu przyrostka lub podciągu. Zauważ, że w case
konstrukcjach, w przeciwieństwie do nazw plików, *
pasuje dowolny znak, w tym a /
lub inicjał .
.
W powłokach, które implementują [[ … ]]
składnię (tj. Bash, ksh i zsh), można jej użyć do dopasowania łańcucha do wzorca. (Zauważ, że [
polecenie może testować tylko ciągi pod kątem równości.)
if [[ $PWD/ = /home/* ]]; then …
Jeśli konkretnie testujesz, czy bieżący katalog znajduje się pod spodem /home
, prosty test podciągów nie wystarczy, ze względu na dowiązania symboliczne.
Jeśli /home
jest to własny system plików, sprawdź, czy bieżący katalog ( .
) znajduje się w tym systemie plików.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Jeśli masz NetBSD, OpenBSD lub GNU (tj. Linux) readlink
, możesz użyć readlink -f
do usunięcia dowiązań symbolicznych ze ścieżki.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
W przeciwnym razie możesz użyć pwd
do wyświetlenia bieżącego katalogu. Należy jednak uważać, aby nie używać wbudowanej powłoki, jeśli powłoka śledzi cd
polecenia i zachowuje nazwę użytą do uzyskania dostępu do katalogu, a nie jego „rzeczywistą” lokalizację.
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Wersja surowa:
[ ${PWD:0:6} = "/home/" ]
Ma tę wadę, że najpierw trzeba liczyć postacie i nie można go zastąpić /home/
czymś ogólnym $1
.
edit (dzięki @ Michael) za uogólnienie do porównania z $VAR
jednym, którego można użyć
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
jest długością $var
, więc możesz ją uogólnić jako[ "${PWD:0:${#1}}" = "$1" ]
Nie rozumiem tego pytania zbyt dobrze, ale aby znaleźć rodzica $ PWD , zrób to dirname $PWD
. Aby znaleźć rodzica rodzica, uruchom dirname $(dirname $PWD)
itd.
/
. Ok, mógłbym sprawdzić rekurencyjnie, ale czy nie jest coś łatwiejszego?
Używanie awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
Hm, szkoda, że [
nie ma opcji testowania STRING1 starts with STRING2
warunku.
Możesz spróbować echo $PWD | grep '^$VAR'
, ale może zawieść w interesujący sposób, gdy VAR
zawiera specjalne symbole.
awk
„s index
funkcja powinna być w stanie wykonać trick. Ale wszystko to wydaje się po prostu zbyt ciężkie, aby można było tak łatwo przetestować.
Jeśli znaleziona część ścieżki zostanie znaleziona, „opróżniam” zmienną:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
A gdyby to był [kod-golf] ( stackoverflow.com/questions/tagged/code-golf) pytanie, pobiłbyś mnie o dwa znaki ;-) Także wygląda bardziej czytelny ...