Zawsze staram się trzymać POSIX sh
zamiast używać rozszerzeń Bash, ponieważ jednym z głównych punktów skryptów jest przenośność (oprócz łączenia programów, a nie ich zastępowania).
W sh
istnieje łatwy sposób sprawdzić dla „is-prefix” stanie.
case $HOST in node*)
# Your code here
esac
Biorąc pod uwagę wiek, tajemny i kruchy sh (a Bash nie jest lekarstwem: jest bardziej skomplikowany, mniej spójny i mniej przenośny), chciałbym zwrócić uwagę na bardzo fajny aspekt funkcjonalny: chociaż niektóre elementy składniowe case
są wbudowane , powstałe konstrukcje nie różnią się niczym od innych zadań. Można je składać w ten sam sposób:
if case $HOST in node*) true;; *) false;; esac; then
# Your code here
fi
Lub nawet krócej
if case $HOST in node*) ;; *) false;; esac; then
# Your code here
fi
Lub nawet krócej (tylko !
jako element językowy - ale teraz jest to zły styl)
if ! case $HOST in node*) false;; esac; then
# Your code here
fi
Jeśli lubisz wyrażać się jasno, zbuduj swój własny element językowy:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
Czy to nie jest całkiem miłe?
if beginswith node "$HOST"; then
# Your code here
fi
A ponieważ sh
zasadniczo są to tylko zadania i listy ciągów (i procesy wewnętrzne, z których składają się zadania), możemy teraz nawet wykonać lekkie programowanie funkcjonalne:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; }
all() {
test=$1; shift
for i in "$@"; do
$test "$i" || return
done
}
all "beginswith x" x xy xyz ; checkresult # Prints TRUE
all "beginswith x" x xy abc ; checkresult # Prints FALSE
To jest eleganckie. Nie, że zalecałbym używanie sh
do czegoś poważnego - zbyt szybko psuje się w rzeczywistych wymaganiach (brak lambd, więc musimy używać łańcuchów. Ale zagnieżdżanie wywołań funkcji za pomocą łańcuchów nie jest możliwe, potoki nie są możliwe itp.)