Messed up my .bash_profile remotely, can't ssh back in
Solution 1
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.
Solution 2
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
).
Solution 3
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
Solution 4
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.
einpoklum
Made my way from the Olympus of Complexity Theory, Probabilistic Combinatorics and Property Testing to the down-to-earth domain of Heterogeneous and GPU Computing, and now I'm hoping to bring the gospel of GPU and massive-regularized parallelism to DBMS architectures. I've post-doc'ed at the DB architecture group in CWI Amsterdam to do (some of) that. I subscribe to most of Michael Richter's critique of StackOverflow; you might want to take the time to read it. If you listen closely you can hear me muttering "Why am I not socratic again already?"
Updated on September 18, 2022Comments
-
einpoklum almost 2 years
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 anexec 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 over 4 yearsI +1'ed you, but it's more convenient to have bash then just plain sh, like @styrofoamfly suggests...
-
chepner over 4 yearsGiven 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. -
spuck over 4 yearsThis 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.
-
Kilian Foth over 4 years@spuck
sh
might be the same binary asbash
, but it will still change its behaviour when invoked as "sh" (including not reading Bash-specific files) for exactly this reason. -
pts over 4 yearsFor beginners who don't know
vi
,nano
,nano-tiny
ormcedit
are convenient choices. (These editors are not always installed, but it's worth a try.) -
einpoklum over 4 yearsSo, this will work, but you're over-complicating the explanation and eventually suggesting a slight variation on existing answers.
-
pts over 4 years@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 over 4 years@einpoklum-reinstateMonica: 4. Not all users are comfortable running a text editor within an SSH session. This answer provides fixes avoiding that.
-
einpoklum over 4 years1. 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. -
pts over 4 years1. 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 over 4 years@einpoklum-reinstateMonica: I'm happy that you have many fixes to choose from, and I'm happy that with my answer I provided value for users who have other login scripts messed up, and/or who are not comfortable running a text editor within an SSH session.
-
einpoklum over 4 yearsOther answers already provide solutions for those cases, actually.
-
JoL over 4 yearsYou 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 doingssh -t user@host bash
you have a login non-interactive shell invoking a non-login interactive shell, so neither reads it. -
pts over 4 years@einpoklum-reinstateMonica: I disagree with the opinion that other answers provide solutions for all those cases this answer provides a solution for. Examples (which I already mentioned several times, but I repeat it here for clarity): 2. A different fix is needed depending on which login script is broken. 3. Provides fix for a broken ~/.bashrc . 4. Not all users are comfortable running a text editor within an SSH session. This answer provides fixes avoiding that. (We can argue if
ed
in another answer is a viable solution for those users, I think it isn't.) -
einpoklum over 4 years@JoL: Please go ahead and edit the answer to reflect that.
-
JoL over 4 years@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 thebash
thatssh
executes is a login shell. It's thebash
thatbash
executes that is not. The process hierarchy issshd -> bash (login non-interactive) -> bash (non-login interactive)
.