如何将函数参数“注入”到已定义的变量中,如本例所示?
mood="i am $1 happy"
happy ()
{
echo "$mood"
}
happy "very"
电流输出:
i am happy
期望的输出:
i am very happy
谢谢!
编辑:
现实世界的例子是:我在另一个文件中有很多可翻译的字符串,如下所示:
installing="Installing"
installation_started="The installation of <app> started at <date>"
installation_ended="The installation of <app> ended at <date>"
还有一个函数:
apt_get_install ()
{
echo "$installing $1..."
echo "$installation_started"
apt-get -y install "$1"
echo "$installation_ended"
}
apt_get_install <app>
然后我想注入<app>
到输出。
答案1
这应该有效。要非常小心eval
,永远不要在用户输入上使用eval
,它会执行任何操作。
mood='i am $1 happy'
happy ()
{
eval echo "$mood"
}
happy "very"
答案2
您似乎想以各种语言向用户提供信息性消息。如果您想正确执行此操作,您可能应该使用专门为此目的设计的软件。在 GNU 世界里,有gettext
这可能对你有用。 (这不是一个需要解决的小问题!)
下面的文本解决了更新之前的问题以及更新后的问题的一部分(在我注意到它是关于提供翻译的消息之前):
您的示例没有多大意义,因为您的函数只是 的别名echo
。您可以轻松地将您的happy
函数称为
happy "I am $adjective happy" # $adjective would be the string "very"
除此之外,听起来标准printf
函数也很有用:
adjective='very'
printf 'I am %s happy\n' "$adjective"
printf
接受一个或多个参数,其中第一个是静止的描述输出格式的字符串,可能包含占位符,其余参数由占位符引用。
如果消息是静态格式字符串,则只需使用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
有关的:
答案3
尝试下面的代码,
function happy ()
{
mood="i am $1 happy"
echo "$mood"
}
happy "very"
或者尝试下面的一个,
function happy ()
{
echo "i am $1 happy"
}
happy "very"
答案4
和zsh
:
mood='I am $1 happy'
happy () {
printf '%s\n' ${(e)mood}
}
happy very
参数扩展标志导致所有参数扩展、算术扩展和命令替换在变量的内容中进行计算(或e
前面的反斜杠可用于阻止它们)。$
`
e
另一种避免诸如or 之类危险的方法eval
是使用gettext
s envsubst
,您可以在其中准确指定要替换的内容:
mood='I am $HOWMUCH happy'
happy() {
HOWMUCH=$1 envsubst <<< "$mood"
}
happy very
虽然<<<
它也是一个 zsh 扩展,但它现在受到其他一些 shell 的支持,包括bash
.
如果您想确保只有(或) 被替换,请替换envsubst
为。envsubst '$HOWMUCH'
$HOWMUCH
${HOWMOUCH}
通过ksh93
或zsh
,您还可以使用:
mood='I am %1$s happy\n'
happy() {
printf "$mood" "$@"
}
printf
在不支持指定%1$s
要使用哪个参数的其他实现中,在这种特殊情况下,您可以使用%s
。如果格式为%s %s
,则第一个%s
获取第一个参数,第二个获取第二个参数。您可以使用或%2$s %1$s
来反转顺序。在其他实现中,您可以使用此技巧:ksh93
zsh
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"
这将打印I'm in a formidable mood
给英语用户和Je suis d'une humeur formidable
法语用户。我们将参数传递两次并使用%.0s
(字符串截断为零宽度)来丢弃我们不希望能够以不同顺序使用这些参数的参数。