web-dev-qa-db-ja.com

エイリアス拡張を使用してzshにパイプする方法は?

私はそれをzshにパイプすることによって履歴から行を実行しようとしています:

cat ~/.zsh_history | cut -d ';' -f 2 | sk --tac | zsh

これは、skを使用してインタラクティブに選択した行が、man zshのようにPATHで使用できるコマンドである場合に機能します。

しかし、それがckのようなエイリアスを持つものである場合、拡張cd .. && lsを実行する代わりに、「コマンドが見つかりません」というエラーが発生します。


編集:また、私が入力した場合:

echo "cd .. && ls" | zsh

親ディレクトリで実行中のlsの出力を出力しますが、コマンドが終了すると、子ディレクトリの元のプロンプトに戻ります。プロンプトに手動で入力してEnterキーを押したかのように、パイプされたものをzshに処理させる方法はありますか?

2
agentofuser

コードをzshにパイプすると、そのコードが別のプロセスで実行されます。このプロセスには、エイリアスや関数などのインタラクティブな設定がなく(_.zshrc_を読み取らない)、シェル変数や現在のシェルの他の状態もありません。現在のディレクトリなど、他のプロセスの状態は、そのプロセスが終了すると失われます。

現在のシェルプロセスでコードを実行するには、コードを引数として(入力としてではなく)evalビルトインに渡します。

_eval "$(<~/.zsh_history cut -d ';' -f 2 | sk --tac)"
_

ただし、履歴エントリを選択するこの特定のユースケースには、別の方法があります。 fcビルトイン 。次のコマンドは、一時ファイルの名前である1つの引数を指定して関数_fcedit_sk_を実行します。関数が呼び出されると、ファイルにはすべての履歴エントリが含まれます(${${(kn)history}[1]}は最も古いエントリのインデックスであり、_-1_は最新のエントリを意味します)。関数が戻ると、zshは、プロンプトで入力したかのように、ファイルに含まれているものをすべて実行します。

_fc -e fcedit_sk ${${(kn)history}[1]} -1
_

_fcedit_sk_を、ファイルの内容に対してskを呼び出し、その出力をファイルに書き戻す関数にします。 skがわからないので、これより簡単な方法があるかどうかわかりません。

_fcedit_sk () {
  local output
  output=$(sk --tac <$1)
  if (($?)); then
    echo >|$1 # Cancelled
  else
    print -lr -- $output >|$1
  fi
}
_