>> Als Variante kann man noch im Hinterkopf behalten (für den Fall,
>> dass man es mal brauchen sollte):
>>
>>
>> ${parameter:+:} false
>>
>> prüft, ob es den Parameter «parameter» gibt und er einen
>> nicht‐leeren Inhalt hat.
>
> Das ist dann doch aber nur eine kompliziertere Schreibweise von
>
>
> [ "$parameter" ]
>
> oder gibt es da noch Randbedingungen, die mir gerade entgehen?
>
Gemäß dem POSIX‐Standard liefert das dasselbe Ergebnis, wenn die
Shell‐Option «-u» («Betrachte den Versuch, einen
nicht‐vorhandenen Parameter zu expandieren, als Fehler, der den
Kommando‐Start verhindert.») ausgeschaltet ist.
Daher müsste das Kommando also, um von der Stellung der
Shell‐Option «-u» unabhängig zu sein, so aussehen:
[ "${parameter-}" ]
Ich sehe aber zwei Gründe, die mich das andere Verfahren
vorziehen lassen:
Erstens traue ich trotz des POSIX‐Standards nicht so recht, was
das Kommando «[» (was nur ein zweiter Name für das Kommando
«test» ist, s. u.) tut, wenn «"$parameter"» beispielsweise zu
«!», «(» oder «)» expandiert. Sven Mascheck hat dazu
Untersuchungen mit verschiedenen (historischen) Implementationen
angestellt (<
https://www.in-ulm.de/~mascheck/various/test/>) und
vom POSIX‐Standard abweichendes Verhalten gefunden.
Um diese Unterschiede zu umgehen, würde ich also das Kommando
abändern und lieber so schreiben:
[ "${parameter:+vorhanden_und_nicht_leer}" ]
Das liefert im Fall, dass der Parameter einen nicht‐leeren Inhalt
hat, den auch für «[» (oder «test») ungefährlichen Aufruf
[ 'vorhanden_und_nicht_leer' ]
und im Fall, dass der Parameter nicht vorhanden oder zwar
vorhanden, aber leer ist, den Aufruf
[ '' ]
Wegen «"${parameter:-vorhanden_und_nicht_leer}"» schaut sich
bereits der Shell an, ob es den Parameter gibt und er einen
nicht‐leeren Inhalt hat und liefert, wenn das der Fall ist, den
Ersatzwert «vorhanden_und_nicht_leer», ansonsten den Ersatzwert
«». Damit werden beide Tests: das Vorhandensein und das
Nicht‐leer‐Sein des Parameters bereits vom Shell erledigt.
Dann aber ist es, wenn man es sich genau überlegt, unsinnig, den
Shell dem Kommando «[» bzw. «test» einen Parameter übergeben zu
lassen, von dem er den Inhalt bereits kennt und von dem er daher
auch bereits wissen könnte, was «[» als Exit‐Status liefern
wird.
Im Gegensatz dazu nutzt das Kommando
${parameter:+:} false
das aus: Der Shell weiß bereits, ehe er das Kommando
zusammenstellt, über das Vorhandensein und den Inhalt des
Parameters bescheid und entscheidet dann, ob er das (interne)
Kommando
: false
oder das möglicherweise externe Kommando
false
aufruft. Weil das Aufrufen eines externen Kommandos im Vergleich
zu dem, was der Shell intern rechnen muss, sehr viel aufwendiger
ist, kann man, wenn man will, sich noch eine Shell‐Funktion mit
Namen «false» definieren (wenn der Shell kein eingebautes
Kommando «false» kennt), um das Starten des externen Programms
«false» zu verhindern:
false()
{
! :
}
Anmerkung: Man fällt leicht darauf herein, im Kommando
[ "${parameter:+vorhanden_und_nicht_leer}" ]
die eckigen Klammern für Teil der Shell‐Grammatik zu halten. Das
entspricht aber nicht der Wirklichkeit: «[» ist wie
beispielsweise «test», «echo» oder «ls» ein simple command, nur
mit dem Unterschied zu «test», dass «[» als letzten Parameter
noch «]» verlangt, damit der Kommando‐Aufruf «schön aussieht»
(und dem Anwender ein X für ein U vormacht); während «test» auf
solchen Firlefanz verzichtet.
Dass es sich bei «[ … ]» wirklich nicht um Shell‐Syntax handelt,
kann man sehen, wenn man dem Shell die beiden folgenden
Kommandozeilen vorlegt und seine Reaktion darauf vergleicht:
{
( true ; printf 'Exit-Status: %s\n' "$?"
}
{
[ true ; printf 'Exit-Status: %s\n' "$?"
}