Niebelung
Niebelung

Reputation: 543

Here document as an argument to bash function

Is it possible to pass a here document as a bash function argument, and in the function have the parameter preserved as a multi-lined variable?

Something along the following lines:

function printArgs {
echo arg1="$1"
echo -n arg2=
cat <<EOF
$2
EOF
}

printArgs 17 <<EOF
18
19
EOF

or maybe:

printArgs 17 $(cat <<EOF
18
19
EOF)

I have a here document that I want to feed to ssh as the commands to execute, and the ssh session is called from a bash function.

Upvotes: 54

Views: 23107

Answers (5)

Robokop
Robokop

Reputation: 926

The way to that would be possible is:

printArgs 17 "$(cat <<EOF
18
19
EOF
)"

But why would you want to use a heredoc for this? heredoc is treated as a file in the arguments so you have to (ab)use cat to get the contents of the file, why not just do something like:

print Args 17 "18
19"

Please keep in mind that it is better to make a script on the machine you want to ssh to and run that then trying some hack like this because bash will still expand variables and such in your multiline argument.

Upvotes: 41

J&#233;r&#244;me Pouiller
J&#233;r&#244;me Pouiller

Reputation: 10197

xargs should do exactly what you want. It convert standard input to argument for a command (notice -0 allow to preserve newlines)

$ xargs -0 <<EOF printArgs 17
18
19
EOF

But for you special case, I suggest you to send command on standard input of ssh:

$ ssh host <<EOF
ls
EOF

Upvotes: 3

starfry
starfry

Reputation: 9943

Building on Ned's answer, my solution allows the function to take its input as an argument list or as a heredoc.

printArgs() (
  [[ $# -gt 0 ]] && exec <<< $*
  ssh -T remotehost
)

So you can do this

printArgs uname

or this

printArgs << EOF
uname
uptime
EOF

So you can use the first form for single commands and the long form for multiple commands.

Upvotes: 9

Dennis Williamson
Dennis Williamson

Reputation: 360105

If you're not using something that will absorb standard input, then you will have to supply something that does it:

$ foo () { while read -r line; do var+=$line; done; }
$ foo <<EOF
a
b
c
EOF

Upvotes: 24

Ned Deily
Ned Deily

Reputation: 85045

One way to feed commands to ssh through a here doc and a function is as so:

#!/bin/sh
# define the function
printArgs() {
echo "$1"
ssh -T remotehost
}
# call it with a here document supplying its standard input
printArgs 17 <<EOF
uname
uptime
EOF

The results:

17
Linux remotehost 2.6.32-5-686 ...
Last login: ...
No mail.
Linux
 16:46:50 up 4 days, 17:31,  0 users,  load average: 0.06, 0.04, 0.01

Upvotes: 0

Related Questions