69

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.
  • Assuming this is your machine, so you know the root password, why not simply log in as root? – jamesqf Nov 25 '19 at 17:14
  • 4
    @jamesqf: That should really not be possible. – einpoklum Nov 25 '19 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 '19 at 4:38
  • 4
    @jamesqf: I have physical access to the machine when I'm near it; now I'm remote. – einpoklum Nov 26 '19 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. – Piskvor left the building Nov 26 '19 at 13:37
129

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.

| improve this answer | |
  • 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 '19 at 17:28
  • @JoL: Please go ahead and edit the answer to reflect that. – einpoklum Nov 26 '19 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 '19 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).

| improve this answer | |
  • 1
    I +1'ed you, but it's more convenient to have bash then just plain sh, like @styrofoamfly suggests... – einpoklum Nov 23 '19 at 23:05
  • 46
    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 '19 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 '19 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. – Kilian Foth Nov 26 '19 at 7:31
20

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
| improve this answer | |
  • 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 '19 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.

| improve this answer | |
  • 1
    So, this will work, but you're over-complicating the explanation and eventually suggesting a slight variation on existing answers. – einpoklum Nov 26 '19 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 '19 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 '19 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 '19 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 '19 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.