jirutka / esh Goto Github PK
View Code? Open in Web Editor NEWSimple templating engine based on shell.
License: MIT License
Simple templating engine based on shell.
License: MIT License
First of all great job
I have always been looking for a template engine that works only with shell binaries.
The advantage for me is I don't need to install any annoying dependencies like with other template engines for example on python.
But I have a problem. The new lines are not present on the output if the preview line is a esh tag.
I am working with openwrt and I do have a lot off image. So that I do not have duplicated configuration files.
I sqashed them in one file as an template for esh to generate the different uci image configuration out of this file.
It works as expected, with a small bug I think.
The new line --><--- NEWLINE MISSING IN OUTPUT
(see: Example code) is not present on the output. And if i remove the -
in the if
statement the line above <% fi %>
. I get two new lines! So I do not know what is the problem. Is this maybe a bug?
Example code:
config interface 'lan'
<% if [ "$common_customer" = "abc" ]; then -%>
option proto 'none'
<% else -%>
option proto 'static'
option netmask '255.255.255.0'
<% fi -%>
option ifname 'eth1.1'
option force_link '1'
<% if [ "$common_customer" = "123" ]; then -%>
option ipaddr '192.168.0.1'
<% elif [ "$common_customer" = "xyc" ]; then -%>
option ipaddr '192.168.0.254'
<% elif [ "$common_customer" = "abc" ]; then -%>
<% else -%>
option ipaddr '192.168.0.50'
<% fi -%>
--><--- NEWLINE MISSING IN OUTPUT
config interface 'wan'
option ifname 'eth0'
<% if [ "$network_wan_auto" != "yes" ]; then -%>
option auto '0'
<% fi -%>
<% if [ "$network_wan_metric" != "default" ]; then -%>
option metric '<%= $network_wan_metric %>'
<% else -%>
<% if [ "$common_customer" != "123" ]; then -%>
option metric '100'
<% fi -%>
<% fi -%>
option proto 'dhcp'
Current state: opened PR gentoo/gentoo#6222
nginx.tpl.esh
access_log <%= ${HOME}/nginx_access.log %> main;
error_log <%= ${HOME}/error.lg %>;
root <%= ${HOME}/APP_NAME %>;
<% if [ -z "$location" ] || [ "${location}" == "/" ] && [ -n "$backend_url" ];then %>
location / {
proxy_pass <%= $backend_url %>;
proxy_set_header Host $host;
}
<% fi %>
The same process that declared a variable will also report an error!
Hi and thank you for this project that I've been using a bit recently !
Does it support loops ?
Thanks in advance
From the examples I expect this to work:
<% if [ $TEST ]; then %>
This should be printed when TEST is not empty.
<% fi %>
But it doesn't. Am I doing something wrong?
Hi!
First of all, kudos for this great little template engine! The attention to portability and correctness is really appreciated. ๐
I stumbled upon a little issue today as I was using the -o
option: I realized that esh
does not honor the umask value of its parent process and always produces files with the UNIX mode u+rw
(0600) as the file is created by mktemp
and not by esh
itself:
This behavior can cause bugs in situations where the output file mode is expected to be something like rw-r--r--
(i.e. with the common and default 0022
umask value).
I think that replacing the mv
command with something like cat "$tmpfile" > "$OUTPUT"
should fix this.
On another note (not related to the issue above but I've realized this when reading the code), I think that the following line:
would be safer with the quotation marks (the single and double quotes) placed the other way around (and also because the $tmpfile
variable seems to be always set on the occasions where the trap command would be triggered).
In a quite twisted scenario (i.e. where an adversary is able to create arbitrary directories in the filesystem and controlling the TMPDIR
environment variable exposed to esh
using the -o
option) the trap command would then be vulnerable to a shell injection attack.
If the variable is not assigned, it should be empty value "", instead of error message "unbound variable"!
While it should be possible to implement the logic for include-once with the current functionality,
I'm wondering if you have thought of having that functionality built-in and if you'd accept a PR.
Thanks for creating esh btw โ
Hello,
Please note that I create this project for Erlang.mk plugin https://github.com/crownedgrouse/esh.mk using your project. Same LICENCE.
Great project ! Thanks
Is there a good way to import my own utilities globally without manually importing them from every file?
For example, if I have this:
# util.sh
hash_file() {
md5sum $1 | cut -f1 -d ' ' | tr -d '\n'
}
I can then write a template that imports my utility like this:
# my_template.conf.esh
<% . util.sh -%>
foo=123
bar=<% hash_file big_data.dat %>
I'm imagining a flag for esh that allows this on the command line so I don't have to manually import utilities in each of my template files, e.g.: esh -i utils/net.sh -i utils/data.sh -o output.conf input.conf.esh
. My gut is telling me there's some kind of way to do this in the shell by altering the environment or passing some flags to the shell interpreter (-s
flag) without altering esh, but I can't figure it out.
Firstly, thanks for sharing this tool, I'm use ESH to generate SQL scripts from a template and it just works great :)
This is the shell script I'm using:
#!/bin/sh
ESH_VERSION=0.1.1
ESH_FILE_NAME=esh-${ESH_VERSION}
ESH_DOWNLOAD_FILE_NAME=${ESH_FILE_NAME}.tar.gz
ESH_DOWNLOAD_BASE_DIR=/tmp
ESH_DOWNLOAD_DIR=/tmp/${ESH_FILE_NAME}
ESH_DOWNLOAD_PATH=${ESH_DOWNLOAD_BASE_DIR}/${ESH_DOWNLOAD_FILE_NAME}
ESH_BIN=${ESH_DOWNLOAD_BASE_DIR}/${ESH_FILE_NAME}/esh
usage () { echo "Script usage: $(basename $0) -p prefix -c collection_name"; }
while getopts ':p:c:h' OPTION; do
case "$OPTION" in
p) PREFIX="$OPTARG";;
c) COLLECTION="$OPTARG";;
h) usage; >&2 exit 1;;
:) echo "Invalid option: $OPTARG requires an argument" 1>&2;;
?) usage; >&2 exit 1;;
esac
done
shift "$(($OPTIND -1))"
# Download ESH if it wasn't downloaded before
if [ ! -d "$ESH_DOWNLOAD_DIR" ]; then
wget https://github.com/jirutka/esh/archive/v${ESH_VERSION}/${ESH_DOWNLOAD_FILE_NAME} -O ${ESH_DOWNLOAD_PATH}
tar -xzf ${ESH_DOWNLOAD_PATH} -C ${ESH_DOWNLOAD_BASE_DIR}
fi
printf "/*\n"
printf "+------------------------------------------+\n"
printf " Scripts start here\n"
printf "+------------------------------------------+\n"
printf "*/\n"
printf "\n"
${ESH_BIN} template.sql PREFIX=${PREFIX} COLLECTION=${COLLECTION}
printf "\n"
printf "\n"
printf "\n"
printf "/*\n"
printf "+------------------------------------------+\n"
printf " Scripts end here\n"
printf "+------------------------------------------+\n"
printf "*/\n\n"
Probably not the best script, but I have to acknowledge the fact that I'm not very good at shell/bash scripting ๐
Usage example: ./script.sh -p zz -c replies
works just fine-
Now let's say I want to support an option -f
whose argument is a set of table fields in the DDL script, for example: ./script.sh -p zz -c replies -f "my_field varchar(500) DEFAULT NULL"
It would fail with: esh: illegal argument: varchar(500)
Is there a way to somehow escape a variable's value? If not, IMHO it would be a nice feature :)
Cheers.
Hello. I try to use esh, but I need to create more comprehensive solution.
How to correct use for with if in template?
For example:
<% for application in ${applications} ; do -%>
<% if "${application}" == "root" ; then -%>
<% contextPath="/" -%>
<% else -%>
<% contextPath="/$application" -%>
<% fi -%>
<Context path="<%= $contextPath %>" docBase="<%= $application %>.war"/>
<% done -%>
applications="root demo app"
but with this template I get next error:
test.xml:3: root: not found
test.xml:3: demo: not found
test.xml:3: app: not found
esh 0.3.1
Current state: Opened request #1514934
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.