ディレクトリを変更したときのBashタブ全体の更新

ディレクトリを変更したときのBashタブ全体の更新

up私があるディレクトリの上の指定されたディレクトリに簡単に移動できるようにする(私のbashrcの関数として)というコマンドがあります。このコマンドはうまく機能しますが、bashタブ補完機能を追加すると、はるかに便利です。現在のパスのディレクトリを識別し、完了のためにリストする完了スクリプトを作成しました。私が経験している問題は、ディレクトリを変更するたびに完了スクリプトが再ロードされないように見えるため、以前のディレクトリにあるかのように結果が表示されることです。コマンド機能をup追加してコマンドを変更できましたが、exec bash任意のディレクトリ変更コマンドでこれを実行できるかどうかはわかりません。exec bashfor while the command is running を追加すればこれを行うことができるようですが、cdこれを行う最善の方法が何であるかよくわかりません。

たとえば、

端末を開くと、ホームディレクトリにあります。

~$

これを入力すると、次のような結果up <TAB><TAB>が表示されます。

~$ up
username home

ここで、ユーザー名はマイコンピュータのユーザー名です。その後、CDを入力して次のようにdir1/dir2/なりup <TAB><TAB>ました。

~/dir1/dir2$ up
username home

繰り返しますが、ディレクトリを変更しましたが。

私の完了スクリプトとupスクリプトのコードは次のとおりです。

スクリプトを完成させる:

#/usr/bin/env bash
LS=$(echo $PWD)
LSARRAY=${LS//\// }
complete -W "$LSARRAY" up

先頭へ戻るコマンド(.bashrcから)

LS=$(echo $PWD)
LSARRAY=(${LS//\// })
i=1
if [[ $LS == *$1/* ]]; then
  FIND=$1
  if [[ $1 == */* ]]; then
    ARR=(${FIND//\// })
    FIND=${ARR[${#ARR[@]}-1]}
  fi
  while [ "${LSARRAY[${#LSARRAY[@]}-$i]}" != "$FIND" ] && [ $i != ${#LSARRAY[@]} ]; do
    cd ../
    i=$(($i+1))
  done
  exec bash
else
  echo "Did not find directory $1"
fi

ベストアンサー1

以下は、次のことを試みる関数up(プログラミング可能な完了対応を含む)の代替実装です。

  • 任意のパスを使用してください(スペースと改行を含む)。
  • 変数を変更しないでくださいIFS。これは次の場合に便利です。正しい回復;
  • いくつかの特別なディレクトリを明示的に処理します(.ここでは..任意の方法で処理されるため、必要に応じてコードを調整する必要があるかもしれません)。

機能up:

up () {
  local path=$PWD
  case $1 in
    (''|'..')
      cd ..; return ;;
    (.)
      cd .; return ;;
    (/)
      cd /; return ;;
    (*/*)
      printf '"%s" %s\n' "$1" 'contains forward slashes, up will not work' >&2
      return 1 ;;
  esac
  if [[ $path != /* ]]; then
    printf '%s\n' 'PWD is not an absolute path, up will not work' >&2
    return 1
  fi
  until [[ $path = / ]]; do
    path=${path%/*}
    path=${path:-/}
    if [[ ${path%"$1"} != "$path" ]] # You may add && [[ -d ${path%"$1"} ]] to
                            # make "up oo" fail when you are in `/foo/bar`,
                            # while "up foo" would succeed anyway
    then
      cd -- "$path"
      return
    fi
  done
  printf '%s "%s" %s\n' 'Directory' "$1" 'not found' >&2
  return 1
}

完成_up機能と説明(completeコマンド):

_up () {
  local cur last path
  declare -A ancestors
  cur=${COMP_WORDS[$COMP_CWORD]}
  path=$PWD
  if [[ $path != /* ]]; then
    return 1
  fi
  until [[ -z $path ]]; do
    path=${path%/*}
    last=${path##*/}
    last=${last:-/}
    if [[ $last == "${cur}"* ]]; then
      ancestors+=( ["$last"]= )
    fi
  done
  COMPREPLY=( "${!ancestors[@]}" )
  return
}
complete -o nospace -o filenames -F _up up

両方のコードスニペットに配置する必要があります.bashrcバッシュ完了完成した機能や仕様を保存することをお勧めします$XDG_DATA_HOME/bash-completion(詳細については、インクページのFAQを参照)。~/.local/share/bash-completion~/.bash_completion

スラッシュを含む引数は意図的に除外されます。そうでなければ(私の考えでは)foo/bar注意を払う必要があるからですfoo///bar/./../baz(例えば、ある種の正規化の実行)。

連想配列(declare -A)を使用するには、Bash> = 4.0が必要です。

おすすめ記事