My script creates a chroot cage to install GRUB to a USB, run as sudo of course:

SYSTEM_DIRS=(etc bin sbin var lib lib64 usr proc sys dev tmp)


for dir in ${SYSTEM_DIRS[@]}; do
  mount --bind /$dir ${boot_partition}/${dir}

Then execute some commands inside the the chroot:

chroot ${boot_partition}/ touch foo # works fine

But when I want to execute the command exit

chroot ${boot_partition}/ exit

I get:

chroot: failed to execute the command <<exit>>: No such file or directory

Why does this happen and there is a way to fix it?

  • 1
    What do you actually mean by "exit the chroot"? The chroot command changes the root directory for e.g. touch foo (or whatever command you execute), but it does not change it for the script, so "exiting it" makes no sense. exit is a shell built-in, and there is no external equivalent utility, so it can't execute it. – Kusalananda Jun 6 '19 at 21:56
  • @Kusalananda I'm following this: unix.stackexchange.com/a/61888/338177: "You have to first exit the chroot session, usually a simple exit will do:". I don't mean exiting the script, but terminate the chroot. (chroot)root@foo:/# exit – schrodigerscatcuriosity Jun 6 '19 at 22:01
  • 1
    They are probably starting an interactive shell through chroot. That shell has to exit. Extiing the chrooted shell will give control back to the non-chrooted shell session. The chroot command only affects the command that it runs. There is no indication in your question that you run chroot "${boot_partition}/" bash. – Kusalananda Jun 6 '19 at 22:03
  • Which I can do directly on the terminal. – schrodigerscatcuriosity Jun 6 '19 at 22:03
  • @Kusalananda I think I understand now. When I execute all this from the terminal it creates an interactive shell, isn't it? – schrodigerscatcuriosity Jun 6 '19 at 22:08

exit is a shell built-in rather than a standalone executable, which means it cannot be executed by chroot. However, even if it could your command would do nothing.

This command runs /executable in the context of a /path chroot:

chroot /path /executable

It does not leave the caller inside that chroot; there's an implicit exit as soon as /executable finishes running:

mkdir -p /tmp/cr/{bin,lib,lib64}
cp -p /bin/pwd /tmp/cr/bin
cp -p $(find /lib* /usr/lib* -name 'libc.so*') /tmp/cr/lib
cp -p $(find /lib* /usr/lib* -name 'ld-linux-x86-64.so*') /tmp/cr/lib64

/bin/pwd                   # "/root"
chroot /tmp/cr /bin/pwd    # "/"
/bin/pwd                   # "/root"

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.