'\" t .\" Title: esh .\" Author: [see the "AUTHOR(S)" section] .\" Generator: Asciidoctor 2.0.17 .\" Date: 2022-04-10 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" .TH "ESH" "1" "2022-04-10" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 .nh .ad l .de URL \fI\\$2\fP <\\$1>\\$3 .. .als MTO URL .if \n[.g] \{\ . mso www.tmac . am URL . ad l . . . am MTO . ad l . . . LINKSTYLE blue R < > .\} .SH "NAME" esh \- simple template system based on shell .SH "SYNOPSIS" .sp \fBesh\fP [\-d] [\-o \fIoutput\fP] [\-s \fIshell\fP] [\-\-] \fIfile\fP [\fIvariable\fP \fI...\fP] .sp \fBesh\fP <\-h | \-V> .SH "DESCRIPTION" .sp \fBesh\fP (embedded shell) is a templating engine for evaluating shell commands embedded in arbitrary templates. It\(cqs like ERB (Embedded RuBy) for shell, intended to be used for templating configuration files. Unlike ERB it provides support for including one ESH template into another (since version 0.2.0). .sp \fBesh\fP converts template \fIfile\fP, or \fIstdin\fP if \fIfile\fP is \(lq\-\(rq, into a sequence of shell commands. Commands between \fI<%\fP and \fI%>\fP tags are passed as\-is, everything else is escaped and prefixed with \fBprintf\fP command. These commands are eventually evaluated using \fIshell\fP (unless \fB\-d\fP is specified). .SH "OPTIONS" .sp \fB\-d\fP .RS 4 Don\(cqt evaluate template, just dump a shell script. .RE .sp \fB\-o\fP \fIfile\fP .RS 4 Output file or \(lq\-\(rq for STDOUT. Defaults to \(lq\-\(rq. .RE .sp \fB\-s\fP \fIshell\fP .RS 4 Command name or path of the shell to use for template evaluation. It must not contain spaces. Defaults to \(lq/bin/sh\(rq. .RE .sp \fB\-h\fP .RS 4 Show help message and exit. .RE .sp \fB\-V\fP .RS 4 Print version and exit. .RE .SH "ENVIRONMENT" .sp \fBesh\fP may be configured using the following environment variables: .sp \fBESH_AWK\fP .RS 4 Command name of path of the awk program to use. It must not contain spaces. Defaults to \(lqawk\(rq. .RE .sp \fBESH_MAX_DEPTH\fP .RS 4 Maximum include depth. Defaults to 3. .RE .sp \fBESH_SHELL\fP .RS 4 The same as \fB\-s\fP \fIshell\fP. .RE .sp The following extra environment variables are available inside the template and for the processes spawned by \fBesh\fP: .sp \fBESH\fP .RS 4 Path of the \fBesh\fP interpreter. .RE .SH "EXIT STATUS" .sp \fBesh\fP exits with the exit status of \fIshell\fP or awk unless some error has encountered before converting the template. .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB0\fP \- Clean exit, no error has encountered. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB1\fP \- Generic error. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB10\fP \- Invalid usage. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB11\fP \- ESH syntax error. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB12\fP \- Include error: file not found. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ . sp -1 . IP \(bu 2.3 .\} \fB13\fP \- Include error: exceeded max include depth (\fBESH_MAX_DEPTH\fP). .RE .SH "TEMPLATE SYNTAX" .sp ESH has two tags for shell code, a tag for include, comments, and a way to escape tag delimiters. .sp <% commands %> .RS 4 Executes the \fIcommands\fP and replaces this tag with its output on \fIstdout\fP. .RE .sp <%= values %> .RS 4 Executes \fIprintf \*(Aq%s \*(Aq\fP with the \fIvalues\fP as arguments and replaces this tag with the output (without trailing white space). \fIvalues\fP are not quoted or escaped, so all shell substitutions are applied. .RE .sp <%+ filename %> .RS 4 Reads and converts ESH template from the \fIfilename\fP and puts it in place of this tag. Includes are processed recursively, but the depth is limited by \fBESH_MAX_DEPTH\fP. .sp If the \fIfilename\fP is relative, it\(cqs resolved against the directory of the template file in which this tag resides. If the template is read from \fIstdin\fP, the first level includes are resolved against the current working directory. Please note that includes are processed during the conversion, not the evaluation phase, so the \fIfilename\fP cannot be an expression or a variable! .sp Unlike the others, this tag must be closed on the same line, otherwise it\(cqs a syntax error. .RE .sp <%# comment %> .RS 4 Removed from the final output. .RE .sp \-%> .RS 4 May be used instead of \fI%>\fP. It trims the following line break if used at the end of line, otherwise has no trimming effect. .RE .sp <%% .RS 4 A literal \fI<%\fP when used outside of the above tags. .RE .sp %%> .RS 4 A literal \fI%>\fP when used inside of the above tags. .RE .sp Opening and closing tag may not be at the same line. .sp Text outside a tag becomes literal text, but it is subject to any tagged shell code surrounding it. For example, text surrounded by a tagged \fBif\fP statement only appears in the output if the condition is true. .SH "EXAMPLES" .sp .B nginx.conf.esh .br .sp .if n .RS 4 .nf .fam C http { access_log <%= $logs_dir/access.log %> main; resolver <%= $(sed \-En \*(Aqs/^nameserver ([^#]+)/\(rs1/p\*(Aq /etc/resolv.conf) %>; <% if nginx \-V 2>&1 | grep \-q lua\-nginx\-module; then \-%> lua_package_path \*(Aq<%= $(pkg\-config \-\-variable=INSTALL_LMOD lua) %>/?.lua\*(Aq; <% fi \-%> <%+ ./http\-common.esh %> <%# The rest of the config is omitted %> } .fam .fi .if n .RE .sp To generate the resulting configuration file run: .sp .if n .RS 4 .nf .fam C esh \-o nginx.conf nginx.conf.esh logs_dir=/var/log/nginx .fam .fi .if n .RE .SH "AUTHORS" .sp \fBesh\fP\*(Aqs author is Jakub Jirutka. .SH "REPORTING BUGS" .sp Report bugs to the project\(cqs issue tracker at \c .URL "https://github.com/jirutka/esh/issues" "" "." .SH "SEE ALSO" .sp sh(1)