web-dev-qa-db-ja.com

bash-子のディレクトリスタックを継承する

新しく作成したbashで、次のことを行います。

pushd foo
pushd bar
dirs -l -v

私は次のようなものを手に入れます

0  bar
1  foo
2  old_dir

私がそうするなら

bash
dirs -l -v

私だけが得ます

0  bar

screenの代わりにbashを使用しても同じことが起こります。

フォークされたシェルでディレクトリスタックを維持するにはどうすればよいですか?

2
ricab

これが自動的に機能しない理由すべてのATOWは、配列変数のエクスポートを妨げる既知のbashバグです(manページのセクションバグを参照)。残念ながら、DIRSTACKは配列変数です。

Pushd/popd/dirsの代わりに、それらをラップし、それらをスカラー変数に格納して、子プロセスがそれを認識できるようにしました。

以下のコードを入手し、オリジナルの代わりにmypushd/mypopd/mydirsを使用すると、子プロセスは親のスタックを記憶します。これは、名前にコロンが含まれているディレクトリでは機能しないことに注意してください。

バグを見つけたら警告してください」と書いたばかりです。また、もっと簡単な方法を知っているなら、共有してください!

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'
1
ricab