1

Context

I have a script that iterates over a list. At each iteration it is expected to invoke a function that constructs a 'diff' command for comparing two remote files via 'eval'.

The 'diff' command gets its inputs through two process substitutions where each one cats a remote file via 'ssh' that performs a passwordless authentication (through public/private keys).

The 'diff' and 'ssh' executions have been tested out of the script and they work fine.

Code

Here I post a very short version of my script which however produces the same problem:

#!/bin/bash
func(){
   NUM=$1
   echo "func $NUM"
   COMMAND="diff <(ssh user1@server1 'cat file1' ) <(ssh user2@server2 'cat file2' )"
   eval "${COMMAND}"  1>/dev/null
   RESULT=$?
}

LIST="1
2
3
4
5"

echo "$LIST" | while read NUM ; do
   echo "main $NUM"
   func $NUM
done

Expected result

main 1
func 1
main 2
func 2
main 3
func 3
main 4
func 4
main 5
func 5

Problem

The script stops after the first iteration:

main 1
func 1

Question

Do you know why the loop stops? and how to solve it?

Manolo
  • 1,500
  • 1
  • 11
  • 15

1 Answers1

2

It's not the eval nor the process substitution. It's ssh.

ssh by default passes stdin through to the command it runs on the remote server (and passes stdout back from the remote command). That makes it possible to use in a pipeline. However, in this case you don't want ssh to touch stdin since you are using it yourself for the loop.

You can easily get ssh to not use stdin, either by using the -n command line option, or by redirecting stdin to /dev/null:

ssh -n user1@server1 'cat file1'
ssh user1@server1 'cat file1' < /dev/null

The latter would also work in the calling function:

echo "$LIST" | while read NUM ; do
   echo "main $NUM"
   func $NUM < /dev/null
done

I suppose you don't want a lecture on the evils of eval, but I feel obliged to mention that using eval in this fashion is probably unnecessary. I presume you are doing it in order to build up a command which uses process substitution. You can, instead, build up an environment with process substitutions using exec, such as:

exec 10< <(ssh -n user1@server1 'cat file1')
rici
  • 234,347
  • 28
  • 237
  • 341