Introduction

In the shell you can see the use of here documents from time to time. They are very practical if you want to feed some data with line breaks (also referred to as "document") into another programm at the current position ("here") in the shell.

cdist allows you to make use of stdin and thus also of here documents in your types. This article gives you some examples on how you can use them.

Here documents in short

For those who have found this page, but are not familiar with here documents, here is a short example of how you can use them:

cat << eof
Hello world,
this is a here document.
eof

The interesting part of here documents is that you can use parameter expansion, command substitution, and arithmetic expansion (as described in the here documents article linked above - opengroup offers a great reference for shell coders/users):

name="Nico"
cat << eof
Hello $name,

1+1 = $((1+1))

ls ~ = $(ls ~)

eof

Just try it - copy and paste the above code into your shell and it will display the result of 1+1 and the contents of your home directory.

Here documents and stdin in cdist

Whenever you execute a type in a manifest in cdist like this:

__file /tmp/testfile

cdist also reads stdin that is supplied to the type. Not every type that is shipped with cdist makes use of stdin, but __file does (always check the manpage of the cdist types - if a type makes use of stdin, it is documented in there).

Indeed, if __file sees that you use "-" as the value for the source parameter, it will use stdin for the content of the file that it maintains:

echo "Hello file" | __file /tmp/testfile --source -

Instead of using echo, we could also use the previously mentioned here document:

__file /tmp/testfile --source - << eof
Hello world,
this is a here document.
eof

Beware, you could use cat like this

cat << eof | __file /tmp/testfile --source -
Hello world,
this is a here document.
eof

but it is a useless use of cat (UUOC)#Useless_use_of_cat).

Templating using here documents in cdist

Here documents are very powerful and they are very useful for templating. Indeed, the __ungleich_nginx_site type uses a template like this in its manifest:

template_in=$__type/files/nginx-template
template_out=$__object/files/nginx-template

export www_dir="$base_dir/www"
export log_dir="$base_dir/logs"

... (including more exports)

mkdir "$__object/files"
sh -e "$template_in" > "$template_out"

The following code shows the template ($__type/files/nginx-template):

cat << eof

#
# Do not change this file. Changes will be overwritten by cdist.
#

server {
   # Only bind on the reserved IP address
   listen $listen;

eof

servername="$name"

for a in $alias; do
    servername="$servername $a"
done
servername="$servername"

cat <<eof

    server_name $servername;

    location / {
        root $www_dir;
eof

if [ -f "$__object/parameter/locationopt" ]; then
    echo "    # User given location parameters"
    while read line; do
        echo "        $line"
    done < "$__object/parameter/locationopt"
fi

cat <<eof
    }

    access_log $log_dir/access.log;

}

eof

Had fun?

The shell is indeed very powerful, you just need to know how to use it. This is why cdist was even originally written in shell script and is still configured in shell script (and will continue to be so).

If you are shell junkie, you may find more addictive drugs in this blog.