User created MOTD prevents SCP from functioning

public-keyscp

I've created custom MOTDs to be displayed at login via SSH by doing the following:

  1. create a text file in /etc/usermotd/<username> with the message inside
  2. Edit the user's .bashrc file and put the following code:
if [ -f /etc/usermotd/`whoami` ]; then
cat /etc/usermotd/<username>;
fi

It works like I want it to. However…

I've now just found that when I try to SCP something, it doesn't work. I do the scp command and it exits without giving any sort of progress bar or saying that it transferred. When I do scp -vvv, I get

debug1: Authentication succeeded (publickey).
debug2: fd 4 setting O_NONBLOCK
debug2: fd 5 setting O_NONBLOCK
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending command: scp -v -t ~
debug2: channel 0: request exec confirm 1
debug2: fd 3 setting TCP_NODELAY
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: exec request accepted on channel 0

WELCOME
debug2: channel 0: read<=0 rfd 4 len 0
debug2: channel 0: read failed
debug2: channel 0: close_read
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug2: channel 0: input drain -> closed
BigBoss ~/.ssh:-$ debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug2: channel 0: rcvd close
debug3: channel 0: will not send data after close
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug3: channel 0: status: The following connections are open:
  #0 client-session (t4 r0 i3/0 o3/0 fd -1/-1 cfd -1)

debug3: channel 0: close_fds r -1 w -1 e 6 c -1 
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK 
Transferred: sent 2208, received 3352 bytes, in 0.2 seconds
Bytes per second: sent 13207.5, received 20050.5
debug1: Exit status 0

Any Ideas why it's failing to send? Or is there another way I can do this?

Best Answer

It's failing to work because scp expects the remote side to behave exactly "just so", and not scream WELCOME back at it. (It would be nice if it would give an error message, but...).

Use sftp (which doesn't spawn a login shell at all) instead of scp or have your .bashrc detect if it's in an interactive session or not. There seem to be a couple of ways to do this:

if [ -n "$PS1" ]; then
  echo WELCOME
fi;

The other method given there for looking to see if "$-" contains "i" appears to be broken, since [ doesn't do * in string comparisons. This should work though (it checks to make sure $- is set, then checks to see if $- with "i" removed is the same as $-. There's probably a better way but I can't think of it at the second)

if [ -n "$-" -a "${-/i}" != "$-" ]; then
  echo WELCOME
fi; 
Related Topic