1

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)

boot_partition=/media/user/boot

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

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?

5
  • 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. Commented Jun 6, 2019 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 Commented Jun 6, 2019 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. Commented Jun 6, 2019 at 22:03
  • Which I can do directly on the terminal. Commented Jun 6, 2019 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? Commented Jun 6, 2019 at 22:08

2 Answers 2

3

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"
0

I meet same question, my solution is when you execute chroot, append exit after it:

chroot /chroot_path && exit

then if user exit chroot, will exit the whole shell

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.