私は "SH -c command"コマンドを含むスクリプトを使用しています。ここで command は、Bourne シェルとして解釈されない bash のエイリアスです。このエイリアスをBourneシェルに設定し、新しいシェルで動作するようにする方法についてのアイデアはありますか?みんなありがとうございます!
ベストアンサー1
これがLinuxの実際のBourneシェルであれば驚きます。 Bourne シェルは Linux に移植されましたが、通常はデフォルトでインストールもパッケージもされません。
考古学目的でのみ設置できます。
sh
おそらく、Bourneシェル(現在はインタプリタや他のPOSIXsh
言語とも呼ばれます)(また、古代シェルとも呼ばれますsh
(現代sはBourneシェルから派生しましたが、sh
それでも異なります))について混乱している可能性があります。
Bourne シェルにはエイリアスはありません。現代sh
はします。
ただし、エイリアスは現在シェルにローカルです。新しいシェル(bash
、、、、...)を実行すると、sh
新しいシェルはこれらのエイリアスを継承しません。csh
zsh
新しいシェルでこれらのエイリアスを再定義する必要があります。
bash
と互換性のある構文で別名の1つの定義をダンプする方法がありますsh
。だからあなたはこれを行うことができます:
alias foo='echo foo' # alias defined in bash
foo_definition=$(alias foo)
sh -c "$foo_definition
foo"
または簡単に:
sh -c "$(alias foo)
foo"
もう1つの問題は、これがうまくいかないことですsh
。最初に目立つのは、私たちがこれをしないということです:
sh -c "$(alias foo);foo"
どちらが機能しますか?いいえ sh
実装する。
エイリアスは実際にはマクロの拡張と似ているからです。エイリアス拡張は構文解析の前に実行されるため、コマンドを実行alias foo='echo foo'; foo
すると、そのalias
行はすでに構文解析されています。
エイリアス定義を1行に配置して次の行に使用すると、一部のシェルの問題は解決されますが、他のシェル(またはなどyash
)zsh
はsh -c
コード全体を完全に解析するため、エイリアス拡張は機能しません。
ただし、エイリアスは一部のテキストを別のテキストに置き換えるマクロなので、手動で置き換えることをお勧めします。
次のようにしてエイリアス値を取得できます。
eval "$(alias foo | sed '1s/ /_/')"
エイリアスの定義を変数foo
に保存します。$alias_foo
その後、次のことができます。
sh -c "$alias_foo"
エイリアス値をfoo
シェルコードに渡しますsh
。
この目的のために、エイリアスの代わりに関数を使用する方が良いかもしれません。エイリアスと同様に、関数は現在のシェルにローカルです。一部のシェルは、同じインタプリタの他の呼び出しとrc
同じ機能をエクスポートできます。bash
foo() { echo foo; }
export -f foo
sh -c foo
sh
実装されたシステムでのみ利用可能ですbash
(主にApple OS / Xおよび一部のLinuxベースのシステムのみ)。
より移植性の高いアプローチは、エイリアスを使用して関数定義を渡されたコードにダンプすることですsh -c
。
sh -c "$(typeset -f foo); foo"
今回は、関数が言語の実際の構成なので、エイリアスではなく関数で拡張時間と解析時間に問題はありません。
ただし、関数定義に構文的に有効でsh
拡張機能を使用しないコードが含まれていることを確認する必要がありますbash
。