4

My question can be seen as an extension of How do diff over ssh? with a little twist.

Environment

macOS Sierra (10.12.3)
OpenSSH 7.3

Example situation

I am trying to print a diff between two files, one of them is located on a remote host and requires sudo for reading.

If this remote file was readable by my remote user (or if I could execute the command with the sudo flag NOPASSWD) I would simply execute:

diff LOCALFILE <(ssh host 'cat REMOTEFILE')

However I do need to authenticate in order to execute the remote command, which means I have to allocate a pseudo-terminal with ssh -t, and the following execution never completes:

diff LOCALFILE <(ssh -t host 'sudo cat REMOTEFILE')

Troubleshooting

ps shows me that the ssh process is stopped:

STAT     TIME   COMMAND
S+    0:00.00   diff LOCALFILE /dev/fd/12
T     0:00.03   ssh -t host sudo cat REMOTEFILE

The ssh process does not respond to SIGTERM at that point, and the file descriptor above does not exist:

❯ ls -l /dev/fd
total 0
crw--w----  1 me     tty     16,   2 Feb 23 17:36 0
crw--w----  1 me     tty     16,   2 Feb 23 17:36 1
crw--w----  1 me     tty     16,   2 Feb 23 17:36 2
dr--r--r--  1 root   wheel         0 Feb 23 09:33 4

Extra notes

I can observe the exact same behavior any time I use ssh -t within a process substitution, regardless of whether a password is needed or not for sudo (that said I understand the use of -t is questionable if no input is expected on the remote host).

Bottom line

I'm using diff as an example here, but my question is actually more general: is there any way to use a Bash process substitution together with a SSH pseudo-terminal allocation?

1 Answers1

2

You can force sudo to take the password from STDIN using the -S option, per this superuser post. Thus the syntax diff LOCALFILE <(ssh host 'echo <password> | sudo -S cat REMOTEFILE') should do what you need, without the need for a pseudo-terminal.

Jeremy Dover
  • 336
  • 1
  • 6