8

I made a really bad decision on one of my servers.

I deleted /bin/sh. I restarted the server and the server won't run because it needs /bin/sh to start the rc scripts. I can't access single user mode either because sh is needed.

Is there any easy way to reinstall the bourn shell?

I tried copying sh from a live cd, it failed on the ld-elf.so.1 library. So I copied that to /libexec from the livecd to my / partition. It then needs the libedit.so library and I copied that to /libexec but it isn't working this time.

I tried a symlink to /usr/local/bin/bash but that still presents me with "can't find sh" type error. I'm assuming that is because /usr isn't mounted yet because it is done from an rc script.

Any help is greatly appreciated.

voretaq7
  • 79,345
  • 17
  • 128
  • 213
jon
  • 81
  • 2
  • 2
    Oh my. That's um, not good. Time to pull the last tape. – MDMarra Dec 16 '11 at 15:53
  • Your LiveCD woes are *probably* because it's a different version of FreeBSD (or your LiveCD is using a magical squashed binary that is /bin/ABunchOfStuff hardlinked around to different names). What version of FreeBSD are you running? – voretaq7 Dec 16 '11 at 16:43
  • herp-derp version is in the title. Don't mind me. Need coffee. – voretaq7 Dec 16 '11 at 16:52
  • 3
    So... uhm... what compelled you to do this? You make it sound as though it was intentional. – user606723 Dec 16 '11 at 18:33

3 Answers3

8

You need to replace /bin/sh with something; that's the key. If you can get into the FreeBSD loader during startup (with an "ok" prompt) try something like this:

set init_shell=/bin/csh
unset init_script
unset init_path

I got this information from loader(8) from the FreeBSD manual pages (online). I've not done this, but it should work (assuming that /bin/csh is present and executable).

If you have a FreeBSD 8.2 server up and running elsewhere, you could try stealing the /bin/sh from that source and putting that into the system where needed.

Alternately, get a statically built /bin/sh and put that in instead; there won't be any library problems with a statically-built binary.

EDIT: I should have noted: if you boot into /bin/csh, you still have to get something to use instead of /bin/sh. You can get it over the Internet or copy it from another CD or a package or something; using /bin/csh to boot gets you into the machine. Copying over the network requires that you bring up the network; otherwise, copy from a CDROM.

The best ways to avoid this in the future:

  1. Don't delete from /bin! (that's the easy part)
  2. Have a statically built /bin/sh, not dynamically linked.
  3. Have a backup sh such as /bin/sh.static.

Do all three.

Mei
  • 4,560
  • 8
  • 44
  • 53
  • Also a great "get me back up so I can fix this" solution (with the virtue of not requiring you to have a LiveCD to boot off of). – voretaq7 Dec 16 '11 at 16:15
6

OK, First the lecture:

  1. DON'T MESS WITH SYSTEM BINARIES
    Anything in /bin, /sbin and /rescue on FreeBSD should be left alone. Even if you know what you're doing (if you know what you're doing you also know these should be left alone. They're really important -- all of them!)

  2. DON'T delete /bin/sh. EVER. On any *NIX system that has it.
    Really. Don't do it. A LOT of scripts rely on /bin/sh being a Bourne Shell. It breaks the universe.
    If you REALLY want to you can probably safely replace it with a copy of bash like Adam Z suggested, but if you're going to do that you may want to statically link that copy of bash -- It pulls in a lot of libraries, and you may not have those until the system is up and /usr/local is mounted.


Now, how to fix the mess? Two options:

Option 1: Somewhat painful
Head on over to http://www.freesbie.org/ (or the FreeBSD LiveCD of your choice - You can probably even use the recovery CD from http://www.freebsd.org for this). Grab the LiveCD, burn it, and boot it.

Once you're up in the LiveCD environment mount your busted system's root partition, copy the /bin/sh from the LiveCD to your machine, then reboot.

This should get you back up and running -- You may want to follow the instructions for Rebuilding "World", or at least re-compile /bin/sh from a source tree that matches your running system though.

Option 2: Less painful, no LiveCD
If you have another FreeBSD box around you can mooch off of (or some other way to get your fingers on a copy of /bin/sh, bring your FreeBSD machine up in single user mode. Configure the network (or mount whatever media has the replacement shell on it), and copy it into place where it's supposed to be.

Reboot and you should be OK -- same caveats as the LiveCD though if the /bin/sh you grab it isn't from a reasonably-close-to-identical machine.

voretaq7
  • 79,345
  • 17
  • 128
  • 213
  • 1
    Using /bin/bash from another distribution of FreeBSD will only work if the shared libraries are the right version. Better to use something that comes directly from FreeBSD 8.2 instead of an alternative build. However, any FreeBSD 8.x system should be able to provide a statically built shell that would work. – Mei Dec 16 '11 at 16:45
  • @david Good point - `/bin` isn't statically linked anymore. I think the Rescue CDs for the appropriate release of FreeBSD have a usable shell (i.e. one that can just be dumped in place), but it's been a while since I booted one... – voretaq7 Dec 16 '11 at 16:47
4

Instead of symlinking, copy your bash into /bin/sh. Use the ldd command to find any libraries that might reside on filesystems other than rootfs and copy them over to rootfs as well.

Adam Zalcman
  • 780
  • 5
  • 19