2

If, in my newly created bash, I do:

pushd foo
pushd bar
dirs -l -v

I will get something like

0  bar
1  foo
2  old_dir

If I then do

bash
dirs -l -v

I get only

0  bar

The same thing happens if I use screen instead of bash.

How could I maintain the directory stack in the forked shell?

1
  • 3
    The directory stack is kept in the array variable DIRSTACK, so it should be a matter of exporting this variable. In fact, it looks like this variable is exported by default (checked with export -p). So this should work automatically! Well, it doesn't because of a known bash bug that prevents arrays from being exported (see section BUGS in the man pages) :S
    – ricab
    Commented Sep 9, 2013 at 13:16

1 Answer 1

1

The reason why this doesn't work automaticall ATOW is a known bash bug which prevents exporting array variables (see section bugs in man page). Unfortunately DIRSTACK is an array variable.

I created replacements for pushd/popd/dirs which wrap them but store their stuff in a scalar variable, so that children processes are aware of it.

If you source the code below and use mypushd/mypopd/mydirs instead of the originals, children processes will remember their parents' stack. Notice that this won't work with directories whose name includes a colon!

Please warn me if you spot any bug, 'cause I just wrote that. Also, if you know of a simpler alternative, please share!

export SCALARDIRSTACK
export DIRSTACK

update_dirstack()
{
  if [ ! -z "$SCALARDIRSTACK" ]; then
    dirs -c
    # get an array from scalardirstack
    IFS=':' read -a tmp <<< "$SCALARDIRSTACK"
    # traverse in reverse order to pushd stuff into the stack
    for (( idx=${#tmp[@]}-1 ; idx>=0 ; idx-- )) ; do
      # gotta use pushd/popd this to manipulate DIRSTACK
      pushd -n ${tmp[idx]} > /dev/null
    done
  fi
}

update_scalardirstack()
{
  if [ ${#DIRSTACK[@]} -gt 1 ]; then
    SCALARDIRSTACK=$(printf '%q:' ${DIRSTACK[@]:1}) # string from array
  else
    SCALARDIRSTACK=""
  fi
}

scalar_dstack_wrap()
{
  update_dirstack
  $@
  update_scalardirstack
}

alias mydirs='scalar_dstack_wrap dirs'
alias mypushd='scalar_dstack_wrap pushd'
alias mypopd='scalar_dstack_wrap popd'
2
  • backward shell compatibility aside, is there anything preventing one from using array (and thus getting rid of the separator issue (colon in this case)?
    – peterph
    Commented Sep 9, 2013 at 20:13
  • @peterph: the reason for the scalar workaround is apparent in my comment to the original question, but I updated the answer to reflect it as well, so that it is self contained
    – ricab
    Commented Sep 10, 2013 at 8:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .