Use .bashrc without breaking sftp

Solution 1:

Try doing this instead

if [ "$SSH_TTY" ]
   source .bashc_real

Solution 2:

Mike's answer will probably work. But it's worth pointing out that you can accomplish this carefully selecting which startup files to put the verbose stuff in. From the bash man page:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.

The sftp/scp tools start an interactive non-login shell, so .bashrc will be sourced. Many distributions source .bashrc from .bash_profile or vice versa, so it can get confusing. A good trick for testing the cleanliness of your login environment is to ssh in with a command, which simulates the same way scp/sftp connect. For example: ssh myhost /bin/true will show you exactly what scp/sftp sees when they connect.

A simple demo:

[email protected]:~$ echo "echo Hello from .profile" > .profile
[email protected]:~$ echo "echo Hello from .bashrc" > .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
Hello from .bashrc
sazerac:~ insyte$

[email protected]:~$ rm .bashrc

sazerac:~ insyte$ ssh mazer /bin/true
sazerac:~ insyte$

The first test will cause scp/sftp/rsync etc. to break. The second version will work just fine.

Solution 3:

If you're using csh:

if ($?prompt)
  ... interactive stuff ...

And if it's bash:

if [[ $- == *i* ]]; then
  ... interactive stuff ...

or alternatively using bash regular expressions:

if [[ $- =~ i ]]; then
  ... interactive stuff ...

These lines should precede lines where you ouput/echo something back.