[ -f /*.txt ]
würde nur dann true zurückgeben, wenn es eine (und nur eine) nicht ausgeblendete Datei gibt, /
deren Name auf endet, .txt
und wenn diese Datei eine reguläre Datei oder ein Symlink zu einer regulären Datei ist.
Das liegt daran, dass Platzhalter von der Shell erweitert werden, bevor sie an den Befehl übergeben werden (hier [
).
Also , wenn es eine ist /a.txt
und /b.txt
, [
wird 5 Argumente übergeben werden: [
, -f
, /a.txt
, /b.txt
und ]
. [
würde mich dann beschweren, dass -f
zu viele argumente vorgebracht werden.
Wenn Sie überprüfen möchten, ob das *.txt
Muster auf mindestens eine nicht ausgeblendete Datei erweitert wird (regulär oder nicht):
shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
./script "$@" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"
shopt -s nullglob
ist bash
spezifisch, aber Muscheln mögen ksh93
, zsh
, yash
, tcsh
gleichwertige Aussagen.
Beachten Sie, dass diese Dateien beim Lesen des Inhalts des Verzeichnisses gefunden werden. Es wird nicht versucht, auf diese Dateien zuzugreifen. Dies macht es effizienter als Lösungen, die Befehle wie ls
oder stat
in dieser Liste von Dateien aufrufen , die von der Shell berechnet werden.
Das Standardäquivalent sh
wäre:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Das Problem ist, dass bei Bourne- oder POSIX-Shells ein Muster, das nicht übereinstimmt, sich selbst erweitert. Wenn also *.txt
erweitert wird *.txt
, wissen Sie nicht, ob es sich um eine .txt
Datei handelt, die nicht im Verzeichnis enthalten ist, oder um eine Datei, die aufgerufen wird *.txt
. Mit [*].txt *.txt
können Sie zwischen beiden unterscheiden.
/
? Außerdem fehlt Ihnen zuvor ein Semikolonfi
.