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.
6
  • Assuming this is your machine, so you know the root password, why not simply log in as root?
    – jamesqf
    Nov 25, 2019 at 17:14
  • 4
    @jamesqf: That should really not be possible.
    – einpoklum
    Nov 25, 2019 at 18:24
  • 1
    The OP says it's his machine, so I would think he has physical access to it. If not, there surely must be a sysadmin or someone who can. Though I would think that this question ought to occasion a bit of thought about whether not allowing root logins via ssh is really that bad an idea :-)
    – jamesqf
    Nov 26, 2019 at 4:38
  • 4
    @jamesqf: I have physical access to the machine when I'm near it; now I'm remote.
    – einpoklum
    Nov 26, 2019 at 8:11
  • 2
    Physical access is nice and all; but it requires...well...*physical* access. Travel there, climb the tower, defeat the dra- sorry, got a bit carried away there. Nov 26, 2019 at 13:37

4 Answers 4

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.

3
  • 2
    You don't need --noprofile. ssh -t user@host bash already doesn't read the profile. The reason is because the profile is only read for "interactive login shells", and by doing ssh -t user@host bash you have a login non-interactive shell invoking a non-login interactive shell, so neither reads it.
    – JoL
    Nov 26, 2019 at 17:28
  • @JoL: Please go ahead and edit the answer to reflect that.
    – einpoklum
    Nov 26, 2019 at 20:16
  • @einpoklum-reinstateMonica Seems like you beat me to it. However, you miswrote the option name as --newprofile. Also, "since when ssh executes bash as just another command, it's not considered a login shell" is slightly inaccurate. It's probably pedantic of me, but the bash that ssh executes is a login shell. It's the bash that bash executes that is not. The process hierarchy is sshd -> bash (login non-interactive) -> bash (non-login interactive).
    – JoL
    Nov 26, 2019 at 21:40
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).

4
  • 1
    I +1'ed you, but it's more convenient to have bash then just plain sh, like @styrofoamfly suggests...
    – einpoklum
    Nov 23, 2019 at 23:05
  • 47
    Given that you aren't really going to do anything except run an editor to fix .bash_profile one you are logged in, I don't see how it matters what shell features are available.
    – chepner
    Nov 24, 2019 at 19:15
  • 7
    This might work, but you can't count on "sh" actually being a different shell. For example on this Ubuntu box, /bin/sh is a symlink to /bin/dash.
    – spuck
    Nov 25, 2019 at 18:40
  • 10
    @spuck sh might be the same binary as bash, but it will still change its behaviour when invoked as "sh" (including not reading Bash-specific files) for exactly this reason. Nov 26, 2019 at 7:31
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
1
  • For beginners who don't know vi, nano, nano-tiny or mcedit are convenient choices. (These editors are not always installed, but it's worth a try.)
    – pts
    Nov 26, 2019 at 15:02
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.

8
  • 1
    So, this will work, but you're over-complicating the explanation and eventually suggesting a slight variation on existing answers.
    – einpoklum
    Nov 26, 2019 at 15:54
  • @einpoklum-reinstateMonica: My answer adds the following over existing answers: 1. What happens if all login scripts are broken? 2. A different fix is needed depending on which login script is broken. 3. Provides fix for a broken ~/.bashrc . All of this can be relevant for future users who find this question. If you have a way to provide all this additional information and explanation in a simpler way, please suggest an edit.
    – pts
    Nov 26, 2019 at 16:03
  • @einpoklum-reinstateMonica: 4. Not all users are comfortable running a text editor within an SSH session. This answer provides fixes avoiding that.
    – pts
    Nov 26, 2019 at 16:13
  • 1. I didn't ask about "all login scripts". 2. bash --noprofile should be ok., because... 3. When bash is a login shell it doesn't run rc files anyway. Finally, the bash run by sshd is just a command - you can choose the flags you like.
    – einpoklum
    Nov 26, 2019 at 16:23
  • 1
    1. StackExchange is not only for helping the OP, but also for helping anyone having a similar problem in the future, finding this question later. 2. bash --noprofile is a working fix only if ~/.bashrc is not messed up. 3. Correct. Finally, ssh -t host bash --noprofile runs 2 instances of bash: sshd runs /bin/bash -c 'bash --noprofile'. Thus it won't work if ~/.bashrc (sourced by the 1st bash) is messed up, no matter what flags are specified for the 2nd bash, which never gets run.
    – pts
    Nov 26, 2019 at 16:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .