Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Bash Here Documents


How to create Here/inline Documents in Bash?

Bash Here documents can be really helpful templating mechanism when used in Bash scripts. They can generate almost anything, even scripts to compile and run sample Java code!


The syntax of Bash here documents is simple:

# "<<" or "<<-"
    here-document content

How it works: When Bash sees “<<WORD” the it knows that it is a Here Document and reads everything until it finds “WORD” on a single line. If the operator is “<<-WORD” then it removes all leading TAB chars from the input.

For some commands you can just pass read input, but very often its useful to redirect the input to some file using “>>” operator, like in the example below.

Here’s an example of a shell script that takes a package and class name and generates package with sample Java class content:


if [ $# -eq 0 ]; then
    echo "Usage: $0 package class"
    echo "Creates a Java class within specified package."
    echo "Example: $0 com.farenda.solved JavaExampleClass"
    exit 1


echo "Creating Java package dirs: ${PACKAGE_DIR}"
mkdir -p "${PACKAGE_DIR}"

# read until EOF and redirect to the new Java class:
cat <<EOF >> "${PACKAGE_DIR}/${MAIN_CLASS}.java"
package ${PACKAGE};

public class ${MAIN_CLASS} {
    public static void main(String[] args) {
        System.out.println("Hello, world!");

PACKAGE_DIR var is created using Bash variable substitution. The expression ${PACKAGE//.//} means: take value of PACKAGE variable and substitute all dots . with /, to turn Java package name into a path on a filesystem.

You can use any word you like as a delimiter, but EOF is commonly used.

If you want, you can extend the shell script with generation of Java compilation script, like so:
echo "Creating compilation script: ${COMPILER}"
cat <<EOF >> ${COMPILER}
echo "Compiling: javac ${PACKAGE_DIR}/*.java"
javac ${PACKAGE_DIR}/*.java
chmod u+x ${COMPILER}

echo "To compile code execute: ./${COMPILER}"

You can use Bash variable substitution in Here Documents and automate generation of many, many things.

Lets run it to see how it all work:

$> ./ com.farenda.solved SampleClass
Creating Java package dirs: com/farenda/solved
Creating compilation script:

To compile code execute: ./
$> ./
Compiling: javac com/farenda/solved/*.java
$> java -cp . com.farenda.solved.SampleClass
Hello, world!

Isn’t that cool? :-)

Share with the World!