shell解析字符串
我从带有 shell 脚本变量的文件中读取了一个字符串,并希望用像这样的函数中的值替换变量
hello.txt:
-------------
Hello $NAME
a.sh
-------------
function printout
{
echo ???somehow_parse??? $1
}
NAME=Joe
printout "$(cat hello.txt)"
NAME=Nelly
printout "$(cat hello.txt)"
。该示例不是最好的,但它描述了我的问题。换句话说:我可以使用 shell 作为模板引擎吗?
我正在使用 ksh。
I read a string from a file with shell script variables, and want to substitute the variables with values in a function like
hello.txt:
-------------
Hello $NAME
a.sh
-------------
function printout
{
echo ???somehow_parse??? $1
}
NAME=Joe
printout "$(cat hello.txt)"
NAME=Nelly
printout "$(cat hello.txt)"
The example is not the best, but it describes my problem. In other words: can I use shell as a template engine?
I am using ksh.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一般来说,我会选择使用 sed/awk 的搜索和替换方法,如 Kent 的回答 或这个答案。
如果您想要仅使用 shell 的方法,那么标准方法是使用
eval
。然而,这会带来安全风险。例如:注意如何将命令注入到模板中!
但是,您可以使用此方法降低风险:
请注意,这仍然不是万无一失的,因为仍然可以使用
$(cmd)
或`cmd` 注入命令
。简而言之,只有当您了解风险并且可以控制/限制对模板文件的访问时,您才应该使用
eval
。以下是如何将其应用到脚本中的示例:
In general, I would go for a search-and-replace approach using sed/awk such as that shown in Kent's answer or this answer.
If you want a shell-only approach, then the standard way would be to use
eval
. However, this poses a security risk. For example:Notice how a command can be injected into the template!
You can however reduce the risk using this approach:
Do note that this is still not foolproof as commands can still be injected using
$(cmd)
or`cmd`
.In short, you should use
eval
only if you understand the risks and can control/limit access to the template files.Here's an example of how this can be applied in your script:
如果您确定模板文件的内容是完全安全的,即它不包含执行可能损害您的计算机的命令的字符串,那么您可以使用 eval:
示例输出:
If you're sure that the contents of your template file is completely safe, that is, it doesn't contain a string to execute a command that might harm your computer, then you can use eval:
Example output:
像这样?
运行它:
like this?
run it:
我认为最简单的解决方案是使用
basename
实用程序。例如,如果您有以下字符串:
a='/home/you/stuff/myfile.txt'
,您可以使用如下命令:并获得如下所示的输出:
I think the easiest solution is to use the
basename
utility.For instance, if you have the following string:
a='/home/you/stuff/myfile.txt'
you could use commands like:and get output that looks like this: