[ -f /*.txt ]
restituire true solo se esiste un (e solo uno) file non nascosto nel /
cui nome termina.txt
e se quel file è un file normale o un collegamento simbolico a un file normale.
Questo perché i caratteri jolly vengono espansi dalla shell prima di essere passati al comando (qui [
).
Quindi, se c'è una /a.txt
e /b.txt
, [
verrà passato 5 argomenti: [
, -f
, /a.txt
, /b.txt
e ]
. [
si lamenterebbe quindi che -f
vengono dati troppi argomenti.
Se si desidera verificare che il *.txt
modello si espanda in almeno un file non nascosto (normale o meno):
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
è bash
specifico, ma gusci come ksh93
, zsh
, yash
, tcsh
avere istruzioni equivalenti.
Nota che trova quei file leggendo il contenuto della directory, non prova ad accedere a quei file, il che lo rende più efficiente delle soluzioni che chiamano comandi come ls
ostat
su quell'elenco di file calcolati dalla shell.
L' sh
equivalente standard sarebbe:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Il problema è che con le shell Bourne o POSIX, se un modello non corrisponde, si espande a se stesso. Quindi, se si *.txt
espande in *.txt
, non sai se è perché non ci sono .txt
file nella directory o perché c'è un file chiamato *.txt
. L'utilizzo [*].txt *.txt
consente di discriminare tra i due.
/
? Inoltre, ti manca un punto e virgola primafi
.