ループ内の変数拡張を使用したコマンドの生成

ループ内の変数拡張を使用したコマンドの生成

特定のディレクトリで作業するときにローカルエイリアスを作成したいと思います。たとえば、次のようなファイルを次のようにしたいとします。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]"
$

おすすめ記事