Unexpected result while using pipe operator inside a shell variable

0

I have a process that dumps some zipped output to the stdout. What I do with this output is pipe and send it through an SSH tunnel to another machine where it is dumped to a file.

Like so:

/usr/bin/myapp | ssh root@remotemachine "cat > /path/to/output/file.gz"

when I ssh to the machine and invoke this line, everything goes fine. But when I put this command in a shell script like

#!/bin/sh
APP=/usr/bin/myapp
OPTS=--gzip
OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\""
$APP $OPTS $OUTPUT

And then invoke the script, I see garbage on the console, which I can only assume it is the output of myapp, and then this

Unknown parameter '|'
Unknown parameter 'ssh'
Unknown parameter 'root@remotemachine'
Unknown parameter '"cat'
Unknown parameter '>'
Unknown parameter '/path/to/output/file.gz"'

I am guessing that shell sent the $OUTPUT section as an argument to myapp instead of acting on them. So, these "Unknown parameter" were coming from myapp not from the shell.

How I can fix this?

hebbo

Posted 2018-04-30T21:10:00.030

Reputation: 189

have you tried /bin/bash instead of /bin/sh ? – Sirex – 2018-04-30T21:20:50.613

No, the system I am working on does not have bash. I need to restrict the work to ash – hebbo – 2018-04-30T21:21:43.307

Then you shouldn't use bash as a tag. – AFH – 2018-04-30T21:25:30.107

ok...removed it. But I was wondering if my problem is not specific to ash and may in fact happen in bash too. So, I wanted to reach a wider audience. Also, at this point I am not where the problem is. – hebbo – 2018-04-30T21:27:13.463

Answers

0

Ok....I found what I needed. It was the eval command. This in fact was answered here.

So, the script can be modified this way:

#!/bin/sh
APP=/usr/bin/myapp
OPTS=--gzip
OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\""
eval "$APP $OPTS $OUTPUT"

hebbo

Posted 2018-04-30T21:10:00.030

Reputation: 189

0

Your shell parses any command line in a certain sequence. When it encounters $APP $OPTS $OUTPUT it sees there is no pipe operator; later these variables are expanded and | appears but it has no special meaning because it's already too late for this.

The result can be re-evaluated with eval (your answer shows you have already discovered this) but eval may turn out to be a misspelled evil.

Your original approach is flawed because shell variables are not meant to contain code. Functions are for code. Example:

app=/usr/bin/myapp
opts=--gzip
output() { ssh root@remotemachine "cat > /path/to/output/file.gz"; }
$app $opts | output

Note it is a good practice to use lowercase variable names.

Kamil Maciorowski

Posted 2018-04-30T21:10:00.030

Reputation: 38 429

I am not an expert at shell scripting. I will try out your answer. It looks better than mine. – hebbo – 2018-04-30T22:12:38.377