Bashでコマンド出力を実際のコマンドラインとして実行できますか?

Bashでコマンド出力を実際のコマンドラインとして実行できますか?

たとえば、説明します。

私のエイリアスを宣言する行があります~/.bashrc

> grep lsdir ~/.bashrc

alias lsdir='ls -d */'

bashrcにこの行を追加したため、エイリアスはまだ現在のセッション環境に追加されていません。いくつかの構成上の理由ですべてのbashrcをリソースとして使用したくないので、このgrepラインを個別に実行したいと思います。

好奇心と教育的な目的で手書きを書こうとしましたが、成功しませんでした。

私はこれを試しました:

> $(grep lsdir ~/.bashrc)
bash: alias: -d: not found
bash: alias: */': not found

またはこれ:

> "$(grep lsdir ~/.bashrc)"
bash: alias lsdir='ls -d */': No such file or directory

またはこれも:

> $("grep lsdir ~/.bashrc")
bash: grep lsdir ~/.bashrc: No such file or directory

しかし、それらのどれも働かなかった。これを達成する方法はありますか?

答え1

使用できるプロセスの交換一致する行のみを取得します。

source <(grep lsdir ~/.bashrc)

答え2

私は答えを見つけました:

コアは内蔵されていますeval

> eval "$(grep lsdir ~/.bashrc)"
> type lsdir
lsdir is aliased to `ls -d */'

答え3

既存の答えはうまくいく解決策を提供しますが、元のコマンドが機能しない$(grep lsdir ~/.bashrc)理由を説明する答えはありません。

実際、シェルは置換中にコマンドに対して制限的な操作を実行します。単語の分割は行われますが、引用符の処理は行われません。

pi@raspberrypi:~ $ echo 'a'
a
pi@raspberrypi:~ $ echo "echo 'a'"
echo 'a'
pi@raspberrypi:~ $ $(echo "echo 'a'")
'a'

最後の行に示すように、echo 'a'コマンド()と引数()では分割は正確ですが、引数自体は引用されていないため、引用はそのままです。ところで、試してみるとほぼ同じことが起こるecho'a'シェルコマンドを変数に保存

あなたの場合は、alias lsdir='ls -d */'コマンド、alias対応する引数、および予期しない2つのlsdir='ls追加引数(-dおよび*/')に分割されます。alias

すべてのコマンド処理(引用符処理を含む)を再実行できる自然な解決策は、を使用することであり、eval答えの1つがすでに述べています。

答え4

変数を出力として使用できます

torun=$(some commands | adapting/parsing results #be aware of multiline returns too)
${torun} # call the generated command

${torun}議論のために、ここで述べたように、ほとんどの場合、変数をコマンドとして適用するときにエスケープ文字や引用の問題を避けるために、コマンドの結果を解析/分析するためにパイプを使用してサブコマンドを追加する必要があります。

つまり、文字列を変数定義行内で使用できるコマンドにすることを忘れないでください。

典型的な:

torun=$( command | sed '....;.....;....' ) #or awk or any string management tools

関連情報