1

I desire to run a cat heredocument in a single row instead the natural syntax of 3 rows (opener, content, and delimiter). My need to do so is mostly aesthetic as the redirected content aimed aimed to be part of a handbook text file and I would like to save as much rows as I can, in that particular file).

Doing cat <<< TEST > ~/myRep/tiesto tiesto TEST (what I would normally split for 3 parts) results in an errors:

tiesto: No such file or direcotry

TEST: No such file or directory.

Is it even possible to execute one-row heredocuments in Bash?

9

Yes, but you'd be using a an here-string rather than a here-document:

cat >"$HOME/myRep/tiesto" <<<'tiesto'

This will send the string tiesto to cat on its standard input, and it will write the string to the file $HOME/myRep/tiesto through a redirection of its standard output.

Note that here-strings are not standard but are implemented by at least zsh (where it comes from, at the same time as the UNIX version of rc, though that rc and its derivatives like es or akanga don't add an extra newline character in the end), ksh93, bash, mksh and yash.

  • Humbly suggested an edit (you will probably like the title!)... – JohnDoea Jun 9 '17 at 3:56
  • @Benia Ah, I see. I wasn't sure what you wanted to to be actual contents of the document as you delimited the whole thing by TEST. – Kusalananda Jun 9 '17 at 4:03
  • Dear @Kusalananda, I suggest adding a space between > and ~ just to ease the read a bit. I can't suggest this in an edit as it's to few chars. – JohnDoea Aug 9 '17 at 18:53
1

You could put a here-document (as opposed to a here-string), on a single line, by using:

eval $'cat << TEST > ~/myRep/tiesto\ntiesto\nTEST'

Technically, that's one line of code, but the $'...' will expand into a new 3 line code that is evaluated again.

Using eval, you can always put any shell code on one line.

With shells that don't support $'...', you can do:

eval "$(printf 'NL="\n"')"; eval "cat << TEST > ~/myRep/tiesto${NL}tiesto${NL}TEST"

Or

eval "$(printf 'cat << TEST > ~/myRep/tiesto\ntiesto\nTEST')"

Of course here,

echo tiesto > ~/myRep/tiesto

would be a lot simpler. Or for multiple lines:

printf '%s\n' "line 1" "line 2" > ~/myRep/tiesto

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.