FreeBSD 8.2, deleted /bin/sh, can't boot

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.


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.


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.


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.