Em ordem do pior para o melhor:
-
DIRNAME="$(dirname $FILE)"não fará o que você quer se$FILEcontiver espaços em branco ou caracteres globbing\[?*. -
DIRNAME='dirname "$FILE"'está tecnicamente correto, mas os backticks não são recomendados para a expansão de comandos devido à complexidade extra ao aninhá-los. -
DIRNAME=$(dirname "$FILE")está correto, mas somente porque essa é uma atribuição . Se você usar a substituição de comando em qualquer outro contexto, comoexport DIRNAME=$(dirname "$FILE")oudu $(dirname "$FILE"), a falta de cotações causará problemas se o resultado da expansão contiver espaços em branco ou caracteres globbing. -
DIRNAME="$(dirname "$FILE")"é o caminho recomendado. Você pode substituirDIRNAME=por um comando e um espaço sem alterar nada, edirnamerecebe a string correta.
Para melhorar ainda mais:
-
DIRNAME="$(dirname -- "$FILE")"funciona se$FILEcomeçar com um traço. -
DIRNAME="$(dirname -- "$FILE"; printf x)" && DIRNAME="${DIRNAME%?x}"funciona mesmo se$FILEterminar com uma nova linha, pois$()corta as novas linhas no final da saída edirnamegera uma nova linha após o resultado. Sheeshdirname, por que você tem que ser diferente?
Você pode aninhar expansões de comando o quanto quiser. Com $() você sempre cria um novo contexto de cotação, então você pode fazer coisas assim:
foo "$(bar "$(baz "$(ban "bla")")")"
Você não quer tentar isso com backticks.