shopt Expand_aliases を使用しても bash エイリアスは拡張されません。

shopt Expand_aliases を使用しても bash エイリアスは拡張されません。

構文内でエイリアスを実行したいですbash -c

これbash手動説明する:

シェルが非対話型の場合、expand_aliasesシェルオプションを使用して設定しないと、エイリアスは拡張されません。shopt

hiこの例で明示的に設定してもエイリアスが見つからないのはなぜですかexpand_aliases

% bash -O expand_aliases -c "alias hi='echo hello'; alias; shopt expand_aliases; hi"
alias hi='echo hello'
expand_aliases  on
bash: hi: command not found

私は走っていますGNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)

コンテキスト:次のようなスクリプトなど、アイドル優先順位でエイリアスを実行できるようにしたいです。

#!/bin/bash
exec chrt -i 0 nice -n 19 ionice -c 3 bash -c ". ~/.config/bash/aliases; shopt -s expand_aliases; $(shell-quote "$@")"

私のコンテンツが読まれたくbash -iないので、使用を避けたいです。.bashrc

答え1

使用中の同じ行にエイリアスを設定しても機能しないようです。それはおそらく、実際の解析ステップの前にコマンドライン処理の最初にエイリアスを拡張する方法と関係があります。インタラクティブシェルでは:

$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo         # 2 
bash: foo: command not found
$ alias foo='echo bar'; foo         # 3
foo
$ foo
bar

使用されるエイリアスは1行の後ろにあります。 2番目のコマンドでは、設定したエイリアスは見つかりませんが、3番目のコマンドは以前に設定したエイリアスを使用します。

したがって、文字列に改行文字を追加すると機能します-c

$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";\n foo'
foo

bash -O expand_aliases -c ...(代わりにスクリプトで使用することもできますが、shopt改行に役立つという意味ではありません。)

あるいは、エイリアスの代わりにシェル関数を使用することもできます。これは他の方法でも優れています。

$ bash -c 'foo() { echo foo; }; foo'
foo

答え2

ilkkachuの提案に従って、私の意見を答えに置き換えます。

Bashのマニュアル(質問にリンク)は、同じ行にエイリアス定義とコマンドがあるときにエイリアスを処理する方法の説明を提供します。

引用符(明確にするために少し書式設定):

エイリアスの定義と使用に関する規則は多少混乱しています。Bash は、その行または複合コマンドからコマンドを実行する前に、入力の完全な 1 行と複合コマンドを構成するすべての行を常に読み込みます。

エイリアスは、コマンドの実行時ではなく、コマンドの読み込み時に拡張されます。したがって、他のコマンドと同じ行に表示されるエイリアス定義は、次の入力行を読むまで適用されません。行のエイリアス定義の後に続くコマンドは、新しいエイリアスの影響を受けません。

この動作は関数の実行時にも問題になります。エイリアスは、関数定義自体がコマンドであるため、関数が実行されるのではなく、関数定義を読み取るときに拡張されます。したがって、関数で定義されたエイリアスは、関数が実行された後にのみ使用できます。

安全のために、常に別名定義を別々の行に配置し、複合コマンドに別名を使用しないでください。

ilkkachuの答えは、この問題に対するいくつかの考えられる解決策を提供します。

関連情報