Isso deve funcionar. Tenha muito cuidado com eval
, nunca use eval
na entrada do usuário, ele executará qualquer coisa.
mood='i am $1 happy'
happy ()
{
eval echo "$mood"
}
happy "very"
Como posso "injetar" um argumento de função em uma variável definida, como neste exemplo?
mood="i am $1 happy"
happy ()
{
echo "$mood"
}
happy "very"
Saída atual:
i am happy
Saída desejada:
i am very happy
Obrigado!
Editar :
O exemplo do mundo real é: eu tenho um monte de strings traduzíveis em outro arquivo, assim:
installing="Installing"
installation_started="The installation of <app> started at <date>"
installation_ended="The installation of <app> ended at <date>"
E uma função:
apt_get_install ()
{
echo "$installing $1..."
echo "$installation_started"
apt-get -y install "$1"
echo "$installation_ended"
}
apt_get_install <app>
E, em seguida, quero injetar <app>
na saída.
Você parece querer fornecer mensagens informativas a um usuário em vários idiomas. Você provavelmente deve usar um software projetado especificamente para essa finalidade, se quiser fazer isso da maneira certa. No mundo GNU, há gettext
que pode ser útil para você. (Não é um problema trivial para resolver!)
O texto abaixo aborda a questão antes de sua atualização e parte da pergunta atualizada (antes de perceber que se tratava de fornecer mensagens traduzidas):
Seu exemplo não faz muito sentido, já que sua função é apenas um alias para echo
. Você pode facilmente chamar sua função happy
como
happy "I am $adjective happy" # $adjective would be the string "very"
Além disso, parece que a função printf
padrão também pode ser útil para saber:
adjective='very'
printf 'I am %s happy\n' "$adjective"
printf
recebe um ou mais argumentos, em que o primeiro é uma sequência estática descrevendo o formato de saída, possivelmente contendo espaços reservados, e os demais argumentos são referenciados pelos espaços reservados.
Se as mensagens forem de formato estático, use apenas printf
:
apt_get_install ()
{
printf 'Installing %s...\n' "$1"
printf '%s installation started at %s\n' "$1" "$(date)"
apt-get -y install "$1"
printf '%s installation ended at %s\n' "$1" "$(date)"
}
apt_get_install thing
Relacionados:
Experimente o código abaixo,
function happy ()
{
mood="i am $1 happy"
echo "$mood"
}
happy "very"
Ou experimente o abaixo,
function happy ()
{
echo "i am $1 happy"
}
happy "very"
com zsh
:
mood='I am $1 happy'
happy () {
printf '%s\n' ${(e)mood}
}
happy very
Os sinalizadores de expansão do parâmetro e
fazem com que todas as expansões de parâmetros, expansões aritméticas e substituições de comandos sejam avaliadas no conteúdo da variável (a barra invertida na frente do $
ou '
pode ser usada para evitá-las) .
Outra abordagem que evita coisas perigosas como e
ou eval
é usar gettext
, onde você pode especificar exatamente o que deseja substituir:
mood='I am $HOWMUCH happy'
happy() {
HOWMUCH=$1 envsubst <<< "$mood"
}
happy very
Embora envsubst
também seja uma extensão zsh, agora ela é suportada por alguns outros shells, incluindo <<<
.
Substitua bash
por envsubst
se você quiser ter certeza de que apenas envsubst '$HOWMUCH'
(ou $HOWMUCH
) seja substituído.
Com ${HOWMOUCH}
ou ksh93
, você também pode usar:
mood='I am %1$s happy\n'
happy() {
printf "$mood" "$@"
}
Em outras implementações de zsh
que não suportam o printf
para especificar qual argumento usar, neste caso específico, você pode usar %1$s
. Se o formato tiver %s
, o primeiro %s %s
obterá o primeiro argumento, o segundo o segundo argumento. Você pode usar %s
para reverter o pedido com %2$s %1$s
ou ksh93
. Em outras implementações, você poderia usar esse truque:
case $(locale language) in
(*English*) msg="I am in a %s %s%.0s%.0s\n"; mood=mood;;
(*French*) msg="Je suis d'une %.0s%s %s%.0s\n"; mood=humeur;;
esac
mood() {
printf "$msg" "$@" "$@"
}
mood formidable "$mood"
O que imprimiria zsh
para um usuário que fala inglês e I'm in a formidable mood
para um usuário que fala francês. Passamos os argumentos duas vezes e usamos Je suis d'une humeur formidable
(a string truncada para largura zero) para descartar aqueles que não queremos poder usar esses argumentos em ordens diferentes.