1

I'm trying to do this (just an example, not a real life situation):

$ mkdir test; ( cd test; echo "foo" > test.txt ); cat test.txt
cat: test.txt: No such file or directory

However, it fails, since cd test directory change is reverted after subshell is finished. What is a workaround? I can't use script .sh files, everything should be in one command line.

yegor256
  • 102,010
  • 123
  • 446
  • 597

3 Answers3

5

Skip the subshell and use a { ... } block instead (or explain your usecase, since this example does not make so much sense):

$ find
.
$ mkdir dir; { cd dir; echo foo > test.txt; }; cat test.txt
foo
$ cd ..
$ find
.
./dir
./dir/test.txt
Adrian Frühwirth
  • 42,970
  • 10
  • 60
  • 71
  • Thanks, that's exactly what I'm looking for. Maybe you know the answer to this related one: http://stackoverflow.com/questions/18513631/why-pipe-resets-current-working-directory – yegor256 Aug 29 '13 at 14:25
  • @yegor256 Yes, as stated in the answers over there, the pipe creates a subshell. – Adrian Frühwirth Aug 29 '13 at 14:49
3

Why not just?

mkdir test; echo "foo" > test/test.txt; cat test/test.txt

Another way is

mkdir test; cd "$(cd test; echo "foo" > test.txt; echo "$PWD";)"; cat test.txt

Or

mkdir test; (cd test; echo "foo" > test.txt; echo "$PWD" > /some/file); cd "$(</some/file)"; cat test.txt
konsolebox
  • 72,135
  • 12
  • 99
  • 105
1

As commenters have said, a child process can't modify the parent's working directory. You can return a value from the child process for the parent to read, then make the parent act on this value. Meaningless bash example:-

$ mkdir test; DIR=$( cd test; echo "foo" > test.txt; echo test ); cat $DIR/test.txt
crw
  • 655
  • 7
  • 17