特定のディレクトリで作業するときにローカルエイリアスを作成したいと思います。たとえば、次のようなファイルを次のようにしたいとします。local_alias
alias foo='bar'
作業が完了したら、これらのエイリアスを削除するクリーンアップスクリプトを作成したいと思います。それは次のとおりです。
egrep "alias [[:alnum:]]+" local_alias -o|while read i; do
un$i
done
中間行を:に変更すると、echo un$i
出力は正しい形式のunalias
コマンドのように見えますunalias foo
。しかし、書かれたように私はそれを理解しますunalias: foo: not found
。
中間の引数を引用しようとすると"un$i"
取得しますunalias foo: command not found
。
私は何が間違っていましたか?
答え1
エイリアスはシェルによって異なるため、次のようにスクリプトを実行するとき:
#!/bin/bash
...
unalias ....
...
これはサブシェルとして実行され、通常は同じエイリアスを持ちません。問題をさらに複雑にするには、処理する必要がある別の問題があります。スクリプトが終了すると、エイリアスが削除されたサブシェルは消え、エイリアスがそのまま残っている親シェルに戻ります。
私が知っている限り、現在シェルのエイリアスをこのように修正する方法はありません。
ではどうすればいいですか?
これを行うには、現在のシェル自体の範囲内でエイリアスまたは関数を生成できます。
はい
エイリアスソリューション
$ alias unalias_local='egrep "alias [[:alnum:]]+" local_alias -o|while read i; do un$i; done'
機能ソリューション
$ function unalias_local { egrep "alias [[:alnum:]]+" local_alias -o | \
while read i; do un$i; done; }
上記の質問
OPはこの回答にソリューションを提供し、これは自分のシナリオで機能すると言いました。しかし、通常、このようなパイプコマンドチェーンのエイリアスを変更することはできません。これは、各パイプが親シェルにアクセスできないサブシェルを呼び出すためです。だから私たちは以前のスクリプトと同じ問題に戻りました。
この問題を解決するには、別名リストをコマンドの引数として提供できます。
はい
$ alias ali1="cmd1"
$ alias ali2="cmd2"
シェルでエイリアスを確認します。
$ alias | grep -E "ali[12]"
alias ali1='cmd1'
alias ali2='cmd2'
コンテンツlocal_alias
:
$ cat local_alias
alias ali1="cmd1"
alias ali2="cmd2"
このコマンドはファイル内のエイリアス名を解析しますlocal_alias
。
$ grep -oP "(?<=alias )([[:alnum:]]+)" local_alias
ali1
ali2
unalias
次のようにこれらのエイリアスと組み合わせて使用できます。
$ unalias $(grep -oP "(?<=alias )([[:alnum:]]+)" local_alias)
$
今消えたことを確認すると、次のようになります。
$ alias | grep -E "ali[12]"
$
答え2
このコードは別のスクリプトで実行されているようです。これはうまくいきません。実行中のシェルの構成を変更する必要があり、他のプロセスではこれを行うことはできません。このクリーンアップコードは.bashrc
。
2番目の問題は、パイプが子プロセス(サブシェル)も作成することです。したがって、このコードを対話型シェルで実行すると、コマンドはunalias
エイリアスを削除しますが、サブシェルからのみ削除されます。unalias
サブシェルでコマンドを実行しない別の方法が必要です。
いくつかの回避策がありますが、最も簡単な方法はエイリアスリストを作成してからコマンドをunalias
一度実行することです。エイリアスには特殊文字を含めることはできないため、エイリアスリストの単語分割は罰金を生成しますunalias
。
unalias $(egrep -o "alias [[:alnum:]]+" local_alias)