groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Groff] What does 'groff <<<foo' do?


From: Ralph Corderoy
Subject: Re: [Groff] What does 'groff <<<foo' do?
Date: Mon, 03 Dec 2012 12:46:16 +0000

Hi,

Johann wrote:
> On 12/02/2012 07:40 PM, Clarke Echols wrote:
> > In a recent email the syntax:
> >
> >      groff <<<foo ...
> >
> > was used.
>
> It's called "Here string" or "here document" and used extensively in
> Bash / Perl / Python / Ruby programming.

That's mixing two different things together.  The double << is a `here
document', the triple <<< is a `here string'.

Here documents have been around for yonks and are in the Bourne shell,
bash, etc.  Perl and Ruby have their versions as a syntax but for
strings not for I/O redirection.  Python doesn't have them, using
multi-line strings instead.

Lines following the << operator are arranged to be the standard input of
the command up to and not including <<'s operand.  If any part of the
operand is quoted in some way then no variable interpolation is done,
even if the quotes are "" as opposed to '' which would normally expand
variables.

Expansion versus no expansion;  the "" and '' have no effect.

    $ cat <<E
    > $HOME "$HOME" '$HOME' `pwd`
    > E
    /home/ralph "/home/ralph" '/home/ralph' /home/ralph
    $
    $ cat <<\E
    > $HOME "$HOME" '$HOME' `pwd`
    > E
    $HOME "$HOME" '$HOME' `pwd`
    $

Any part quoted affects expansion.

    $ cat <<E"O"F
    > $HOME "$HOME" '$HOME' `pwd`
    > EOF
    $HOME "$HOME" '$HOME' `pwd`
    $

If <<- is used instead of << then runs of leading tabs are removed, but
not general white-space.  It's intended for indenting the document;  I
never use it.

    $ cat <<-E
    >               $HOME "$HOME" '$HOME' `pwd`
    > E
    /home/ralph "/home/ralph" '/home/ralph' /home/ralph
    $
    $ cat <<-E
    >     $HOME "$HOME" '$HOME' `pwd`
    > E
        /home/ralph "/home/ralph" '/home/ralph' /home/ralph
    $

A here string is a bashism where the `word' that is <<<'s operand is fed
to the command on stdin.  This means it follows the normal expansion
rules.

    $ xargs ls -d <<<$HOME
    /home/ralph
    $ xargs ls -d <<<"$HOME"
    /home/ralph
    $ xargs ls -d <<<'$HOME'
    ls: cannot access $HOME: No such file or directory
    $ xargs ls -d <<<"/././.`pwd`"
    /./././home/ralph
    $

bash here currently implements it as a temporary file that's deleted
before the command's run.

    $ ls -l /dev/fd/0 <<<foo
    lr-x------ 1 ralph ralph 64 2012-12-03 12:17 /dev/fd/0 -> 
/tmp/sh-thd-1354535065 (deleted)
    $

I take the point on it not having left to right order but neither has
    bar <foo
compared to
    cat foo | bar
but we rightly shun the latter.  Having used <<< for some years, I'm
just as happy reading `command, its options, then how its I/O is set'
whether it's <, <<, or <<<.

BTW, if you didn't know of <<< then you may be missing out on <() and
friends.  See `Process Substitution' in bash(1).

    join <(sha1sum * | sort) <(cd ../old && sha1sum * | sort)

-- 
Cheers, Ralph.
https://plus.google.com/115649437518703495227



reply via email to

[Prev in Thread] Current Thread [Next in Thread]