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?

4
  • have you tried /bin/bash instead of /bin/sh ? Commented Apr 30, 2018 at 21:20
  • No, the system I am working on does not have bash. I need to restrict the work to ash Commented Apr 30, 2018 at 21:21
  • Then you shouldn't use bash as a tag. Commented Apr 30, 2018 at 21:25
  • 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. Commented Apr 30, 2018 at 21:27

2 Answers 2

1

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.

1
  • I am not an expert at shell scripting. I will try out your answer. It looks better than mine. Commented Apr 30, 2018 at 22:12
1

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" 
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.