I've set up full working debootstrap-ed arm chroot environment. I can chroot in it, run commands, etc.

I am making a script that will customize chroot env, but I struggle with this.

For example:

chroot $target_dir echo this is a test > /tmp/test

Can anyone explain to me, why within this example I get output written on my host environment, not in chrooted?

Just to mention, I could execute f.e.

echo this is a test > $target_dir/tmp/test

but I would like to know why chrooted execution 'fails'


This also works:

chroot $target_dir /bin/bash -c "echo test > /tmp/test"
  • @JeffSchaller what do you mean exactly? – fugitive Aug 27 '17 at 15:02

When you run:

chroot $target_dir echo this is a test > /tmp/test

The > /tmp/test happens "for" the chroot command, much as if you had written:

> /tmp/test chroot $target_dir echo this is a test

If you want the redirection to happen inside of the chroot command, one way would be:

chroot $target_dir sh -c 'echo this is a test > /tmp/test'

... as this puts sh inside the chroot, letting echo see the correct redirected directory.


The redirection isn't actually occurring inside chroot. > /tmp/test is handled by whatever shell you are using. If you actually passed > /tmp/test to chroot, then it would get passed to echo and you'd see

this is a test > /tmp/test

on your terminal. You shell, of course, isn't getting chrooted, so it's perfectly fine with opening /tmp/test. Then, the shell execs the chroot executable, which calls the chroot system call and then execs into echo, which finally writes to the fd. All through this, the original file descriptor that your (unchrooted) shell opened is never modified, so your chrooted echo is able to write to it.

This is a deliberate feature. A process outside the chroot is allowed to open files, and then its chrooted children can only access those files outside the chroot that the parent process deigned to pass to them.

If you want the redirection to take place inside the chroot, you need to spawn a shell that knows how to interpret it:

chroot $dir bash -c "echo this is a test > /tmp/test"

The order of operations is now: fork (with default stdin, stdout, and stderr), exec chroot, chroot (now inside chroot), exec bash (knows how to handle redirection), fork (implementation detail of bash), open file, exec echo (with new stdout).

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.