Tutti dicono che eval è malvagio, e dovresti usare $() come sostituto. Ma mi sono imbattuto in una situazione in cui lo smascheramento non è gestito all'interno di $().
Lo sfondo è che sono stato bruciato troppo spesso da percorsi di file con spazi al loro interno, e così mi piace citare tutti questi percorsi. Più paranoia sul voler sapere da dove provengono tutti i miei eseguibili. Ancora più paranoico, non fidandosi di me stesso e così come essere in grado di visualizzare i comandi creati che sto per correre.
Qui di seguito cerco variazioni sul usando eval vs $(), e se il nome del comando è citato (cuz potrebbe contenere spazi)
BIN_LS="/bin/ls"
thefile="arf"
thecmd="\"${BIN_LS}\" -ld -- \"${thefile}\""
echo -e "\n Running command '${thecmd}'"
$($thecmd)
Running command '"/bin/ls" -ld -- "arf"'
./foo.sh: line 8: "/bin/ls": No such file or directory
echo -e "\n Eval'ing command '${thecmd}'"
eval $thecmd
Eval'ing command '"/bin/ls" -ld -- "arf"'
/bin/ls: cannot access arf: No such file or directory
thecmd="${BIN_LS} -ld -- \"${thefile}\""
echo -e "\n Running command '${thecmd}'"
$($thecmd)
Running command '/bin/ls -ld -- "arf"'
/bin/ls: cannot access "arf": No such file or directory
echo -e "\n Eval'ing command '${thecmd}'"
eval $thecmd
Eval'ing command '/bin/ls -ld -- "arf"'
/bin/ls: cannot access arf: No such file or directory
$("/bin/ls" -ld -- "${thefile}")
/bin/ls: cannot access arf: No such file or directory
Quindi ... questo è fonte di confusione. Un percorso di comando quotato è valido ovunque tranne all'interno di un costrutto $()? A breve, ad esempio più diretto:
$ c="\"/bin/ls\" arf"
$ $($c)
-bash: "/bin/ls": No such file or directory
$ eval $c
/bin/ls: cannot access arf: No such file or directory
$ $("/bin/ls" arf)
/bin/ls: cannot access arf: No such file or directory
$ "/bin/ls" arf
/bin/ls: cannot access arf: No such file or directory
Come si spiega il semplice $($c)
caso?
Le stringhe non quotate vengono valutate immediatamente. c = ("/ bin/ls"/bin/l *) fa qualcosa di molto diverso dal voluto. (guarda con echo "'$ {c [@]}'") c = ("/ bin/ls" "/ bin/l *") allora z = $ ("$ {c [@]}") fallisce. Un array di argomenti non può essere usato bene con $()? – Shenme
Tuttavia, c = ("/ bin/ls" "/ bin/l *") allora z = $ ($ {c [@]}) sembra funzionare bene. È questa la forma eseguibile $() che intendevi mostrarmi? – Shenme