
いくつかのビルド成果物を別のディレクトリにコピーする という名前のスクリプトがあります。その後、コピー先のディレクトリでcpodin
編集します。SHA1SUM
例えば:
cpodin /foo/bar/baz
vim !$/SHA1SUM
fixsha
後者のコマンドを、引数を取らず、SHA1SUM
前のコマンドの最後の引数で指定されたディレクトリを編集するエイリアスにするにはどうすればよいでしょうか?
alias fixsha='vim !$/SHA1SUM'
!$/SHA1SUM
代わりに編集が試行されます/foo/bar/baz/SHA1SUM
。
答え1
Bashはエイリアス展開後に履歴展開を行わないので、 を使って明示的に行う必要がありますhistory
。Bash 履歴ビルトイン以下に抜粋します。
history -ps args
-p
履歴置換を実行する引数結果を履歴リストに保存せずに、標準出力に表示します。-s
引数は、履歴リストの末尾に単一のエントリとして追加されます。
のエイリアスはalias fixsha='vim $(history -p !$)/SHA1SUM'
ほとんどの場合機能しますが、!$
空白を含むパスに展開された場合は意図したとおりに機能しません。パス引数を二重引用符で囲むと、空白でのエスケープが保護され、vim "/foo/bar\ baz/SHA1SUM"
目的の またはvim /foo/bar\ baz/SHA1SUM
それと同等のではなく が結果として表示されますvim "/foo/bar baz/SHA1SUM"
。
したがって、明示的な履歴展開に加えて、eval
引用の 1 つのレイヤーをアンラップすることも必要です。
alias fixsha='eval vim "$(history -p !$)/SHA1SUM"'
注記:上記のエイリアス定義の二重引用符が不要であることに驚かれるかもしれません。これは、と の展開された値の間に空白がなく!$
、/SHA1SUM
bash の単語分割がトリガーされないためです。ただし、単一の引数に展開するという意図を強調するために、二重引用符があるのは良いと思います。