71

I'm using a GNU/Linux system remotely, via SSH.

I mistakenly added something into my $HOME/.bash_profile scriot which causes an error. (To be specific: I added an exec foo command instead of . foo, applied to another bash script without execution permissions, which results in an error.)

Now I can't seem to SSH, SCP or SFTP into my machine: bash, my login shell, tries to run the exec foo command, gets the error and throws me out! I don't have any other account I can access remotely.

Is there something I can do to restore access to the system?

Additional details:

  • Most ports other than for SSH are unavailable since the machine is behind a firewall.
  • It's a Devuan 3 ASCII (~= Debian 10 Beowulf) system.
einpoklum
  • 10,666

4 Answers4

130

As described here you can use

ssh -t user@host bash --noprofile

in fact, as @JoL suggests, you don't even need the --noprofile, since when ssh executes bash as just another command, it's not considered a login shell. Running ssh -t user@host bash will only read the RC files; and running ssh -t user@host bash --norc will not read even those.

48

Try to SSH and run sh instead of bash, e.g.

ssh user@host sh

Then rename (mv) or edit the broken file (ex/vi).

kenorb
  • 26,615
21

Run ssh -t host vi .bash_profile (or the editor of you choice in place of vi) and fix your .bash_profile.

(The -t option may not be needed, depending on which editor you choose.)

If you know exactly what needs to be fixed, you may be able to fix it non-interactively. For example, something like

printf 's/exec foo/. foo/\nwq\n' ssh host ed .bash_profile
chepner
  • 7,041
1

If only ~/.bash_profile is messed up, see the other answers for fixing it. The rest of this answer elaborates on fixing all (other) login scripts.

If you are unlucky enough that you have echo Bad luck; exit 42 in the beginning of both your ~/.bashrc and ~/.bash_profile, and you have /bin/bash as your login shell, and ssh root@host doesn't work either, then its unlikely that you are able to fix it remotely. That's because sshd will insist on running your login shell, and the first /bin/bash will read either ~/.bashrc or ~/.bash_profile, and specifying bash --norc --noprofile is too late, because the /bin/bash run by sshd doesn't have these flags, no matter what you specify in the ssh command-line.

If you've messed up only ~/.bashrc, then run this to fix it:

echo mv -f .bashrc .bashrc.mess | ssh host

If you've messed up only ~/.bash_profile and/or ~/.profile and/or ~/.bash_login, then run this to fix it:

ssh host 'mv -f .bash_profile .bash_profile.mess; mv -f .profile .profile.mess; mv -f .bash_login .bash_login.mess'

After the fix, you can do ssh host as usual, and clean up the login script files in your favorite editor or using scp, sftp or rsync to transfer files and editing them locally.

pts
  • 7,648