help-bash
[Top][All Lists]
Advanced

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

Re: [Help-bash] Is it possible to combine here-doc and pipeline?


From: Andy Chu
Subject: Re: [Help-bash] Is it possible to combine here-doc and pipeline?
Date: Thu, 27 Jul 2017 16:38:40 -0700

On Thu, Jul 27, 2017 at 4:04 PM, Peng Yu <address@hidden> wrote:

>
> I think there is not a way to combine here-doc and pipeline based on
> my test. Could anyone confirm if this is the case? Thanks.
>


Syntactically, a here doc can go anywhere a regular redirect can go.  Since
regular redirects can be combined with pipelines, so can here docs.

Eduardo pointed out this way:

cat <<EOF | sed 's/a/b/g'
> what a wonderful world
> EOF

You can also do it like this:


cat <<EOF |
what a wonderful world
EOF
sed 's/a/b/g'

(Although for some reason this only works in batch mode rather than
interactively)

The way to think of it is that here doc delimiter is a placeholder for the
literal string that comes later.  So the last two examples are analogous to:

cat <<< 'here doc' | sed 's/a/b/g'

and

cat <<< 'here doc' |
sed 's/a/b/g'

respectively.

You can also have multiple here docs on a line, like this:

$ cat <<EOF1; cat <<EOF2
> one
> EOF1
> two
> EOF2
one
two

Similarly,

cat <<EOF1 | cat <<EOF2

and

cat <<EOF1 && cat <<EOF2

are also valid.

If you want to know all the gory details, read my blog post:

http://www.oilshell.org/blog/2016/10/17.html

Summary: here docs are parsed in a post-order traversal of the shell AST.
I had no idea about this or even about multiple here docs on a line before
I implemented a shell parser!

This turns out to be trivial to implement, but IMO very hard for the user
to read.  So I would stick with simple uses in your code.  One way to make
it simpler is to wrap the here doc in a function:

f1() {
  cat <<EOF
what a wonderful world
EOF
}

f1 | sed 's/a/b/g/'   # same thing semantically, but semantically there's
no here doc combined with a pipeline.


Andy


reply via email to

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