bashだけで作るぱすわーどまねーじゃ2

by haturatu

3 min read

こんにちは、無能です。
こういう便利な.bashrcあるじゃないですか?

_ssh_hosts() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "$(awk '{print $1}' ~/.ssh/known_hosts | cut -d, -f1 | sort -u)" -- "$cur") )
}
complete -F _ssh_hosts ssh

(前にどっかでみつけてパクってきた)

なのでこのbashの便利な組み込みコマンドってめっちゃ便利やな!と思って自分で作ったパスワードマネージャに組み込んで作ってみた。
パスワードマネージャが作りたかったというよりもcompleteを使いたかっただけです。
GitHub - haturatu/ppbash: bashだけで作るオレオレパスワード生成&マネージャ

説明

_usage

引数が渡されなかったときの内部関数で、ヘルパー関数です。実行パスワード生成コマンドを増やした場合にも繰り返し使えるようにしただけです。

_usage() {
  local pass_func="$1"
  local phrase="$2"
  local filename="$3"

  if [[ -z "$filename" ]]; then
    echo "Usage: $pass_func <filename> <phrase>"
    echo
    echo "説明:"
    echo "  $pass_func は指定した <phrase> からパスワードを生成し、"
    echo "  ~/.${pass_func}/ に <filename> という名前で暗号化して保存します。"
    echo
    echo "引数:"
    echo "  <filename> : 保存・読み出しに使う識別名(ファイル名)"
    echo "  <phrase>   : 元となるフレーズ(空白を含む場合は引用符で囲む)"
    echo
    echo "使用例:"
    echo "  $pass_func mymail 'Like a rolling stone'"
    echo
    echo "再利用:"
    echo "  既に保存済みの <filename> を指定すると、そのパスワードを再表示します。"
    echo
    echo "補完:"
    echo "  ${pass_func} <Tab> で保存済みのファイル名が補完されます。"
    echo
    echo "関連コマンド:"
    echo "  ppmenu  : 登録済みのパスワードディレクトリを一覧表示します。"
    echo
    return 1
  fi

  return 0
}

_init_pass_dir

わざわざ書く必要もあるかな?と思いましたが冗長になるのでこれもヘルパー関数を作りました

_init_pass_dir() {
  local dir=$1
  if [[ ! -d $dir ]]; then
    mkdir -p $dir
  fi
}

_pass_list

completeに渡す補完用のファイルを配列に格納しています。
printf "%s " "${passfiles[@]##*/}"はフルパスの配列からファイル名だけを列挙します。
awkみたいなものですが例えば/uoo/ooo/genkiだったらgenkiだけになります。

_pass_list() {
  local dir="$1"
  local passfiles=()

  if [[ -d "$dir" ]]; then
    passfiles=("$dir"/*)
    printf "%s " "${passfiles[@]##*/}"
  fi
}

_register_func_dir

ややこしいから関数名直したほうがいいかもな・・・

関数を配列に格納していきます。
declare -F でbashで定義されてる関数からpbで始まるものを抽出します。
それを配列PASS_DIRSに格納してます。

その後にcomplete -Wはスペース区切りのワードを$fnの関数を入力したときに補完できるようにします。

_register_func_dir() {
  while read -r fn _; do
    local dir="$HOME/.$fn"
    PASS_DIRS+=("$dir")

    complete -W "$(_pass_list "$dir")" "$fn"
  done < <(declare -F | awk '{print $3}' | grep '^pb')
}

complete -Wよりもcomplete -Fのほうが汎用性が高いと思います。
なぜならば、補完するときには関数を実行するため動的に生成します。
-Wは静的な値から補完されますが、最初の方にあったsshの補完のときには

_ssh_hosts() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "$(awk '{print $1}' ~/.ssh/known_hosts | cut -d, -f1 | sort -u)" -- "$cur") )
}
complete -F _ssh_hosts ssh

sshの後にTabを押したら_ssh_hostsが実行されます。
多分後でcomplete -Fで補完できるように未来の俺がするであろう・・・

残りのパスワード生成関数系はあまりおもしろ味がないのでここまで。
【気持ち悪い】 .bashrc だけでできるパスワードマネージャー - SOULMINIGRIG
ココらへんに仕組みは書かれていて、後は基本すでに紹介したヘルパー関数を使ってるだけです。
それではまた。よろしくお願いします。

PGP --- Contact --- Machines --- cat -v