Não está claro o que você quer fazer. $($@)
não faz sentido, mas o que você quer fazer?
O que $($@)
faz:
- Pegue os argumentos da função. Esta é uma lista de strings.
- Divida cada parte mais onde elas contêm espaço em branco¹.
- Pegue cada parte dividida e interprete-a como um padrão curinga. Se o padrão corresponder a qualquer arquivo, substitua a peça pela lista de nomes de arquivos correspondentes.
- Use a primeira parte como o nome de um comando para executar (função, shell embutido ou arquivo executável) e passe as outras partes como argumentos.
- Pegue a saída do comando e divida-a onde ela contiver espaço em branco.
- Pegue cada parte dividida e interprete-a como um padrão curinga. Se o padrão corresponder a qualquer arquivo, substitua a peça pela lista de nomes de arquivos correspondentes.
- Use a primeira parte como o nome de um comando para executar (função, shell embutido ou arquivo executável) e passe as outras partes como argumentos.
Se isso parece complicado, é porque é.
Se você quiser que execute_cmd export MY_VAR=my_val
execute export MY_VAR=my_val
, por que você está incomodando com execute_cmd
?
Existem duas maneiras pelas quais isso pode ser interpretado de maneira sensata.
-
Você deseja passar um comando com parâmetros para uma função. Um comando com parâmetros é uma lista de strings, sendo a primeira um nome de função, um shell embutido ou um arquivo executável. Em seguida, a sintaxe para invocar esse comando nos parâmetros fornecidos é "$@"
.
execute_cmd () {
"$@"
}
execute_cmd export MY_VAR=my_val
As aspas duplas evitam os passos de expansão de divisão e curinga que mencionei acima. Sempre use aspas duplas em torno da variável substituições .
Observe também a natureza dupla do export
keyword / builtin. Enquanto export MY_VAR=$(seq 10)
trabalha na atribuição da saída de seq 10
a $MY_VAR
, pois o shell analisa MY_VAR=$(seq 10)
devido à presença da palavra-chave export
, o shell não analisa MY_VAR=$(seq 10)
como uma atribuição em execute_cmd export MY_VAR=$(seq 10)
, porque o comando não é export
aqui, mas execute_cmd
, então MY_VAR=$(seq 10)
é analisado como em qualquer argumento para qualquer comando normal e split + glob é executado em $(seq 10)
, então você precisa: execute_cmd export MY_VAR="$(seq 10)"
.
-
Você deseja executar um snippet de shell. Um fragmento de shell é uma única string, a ser passada como um único argumento. Para executar uma string contendo código shell, use o eval
builtin.
execute_cmd () {
eval "$1"
}
execute_cmd 'export MY_VAR=my_val'
¹ Assumindo o padrão IFS
. Se você sabe sobre isso, não precisa ler este parágrafo.