グラフィカルログイン時に.profileから機能をエクスポートする方法

グラフィカルログイン時に.profileから機能をエクスポートする方法

私はGDMでUbuntu 18.04を使用しています。私の.bashrcファイルからいくつかのbash機能をエクスポートしようとしています.profile

説明したようにこれはとても良い素材です.bashrc、の主な違いは、.profile後者がログインシェルでのみ実行されることです。

.profile私はエクスポートを使用してに合わないものを得ることに成功しました。したがって、グラフィカルログインシェルでもその情報を正常に取得できることが.bashrcわかります。.profileたとえば、私の$PATH定義は次のようになります。

export PATH="something/bin:$PATH"

.bashrcこれを に入れると、"something/bin"サブシェルを実行するたびに再挿入されます。

$ echo $PATH
something/bin:/usr/local/bin:/usr/bin:/bin
$ bash
$ echo $PATH
something/bin:something/bin:/usr/local/bin:/usr/bin:/bin

しかし、このような関数をエクスポートすると、グラフィカルログインでは機能しないようです。

hello () { echo "hello"; }
export -f hello

bash -lログインしてもコンソールからログインしても、うまく機能します。

したがって、質問は次のようになります。.profileソースが明らかに得られた場合(環境変数が正常にエクスポートされ、明示的にソースがあるとマークされている場合/etc/gdm3/Xsession)、エクスポートされた関数が機能しないのはなぜですか?

ベストアンサー1

これは、「で説明されている問題の特定のケースである可能性が高いです。私のBASH_FUNC_foobar%%環境変数がシェルサブプロセスに設定されていないのはなぜですか?」。

から関数をエクスポートすると、bash特別な名前を持つ環境変数が生成されます。

$ foo () { echo hello; }
$ export -f foo
$ env

...

BASH_FUNC_foo%%=() {  echo hello
}

...

シェルは、シェル関数がこれを実行できないため、これを行います。本物次へエクスポート機能そのため、「特殊環境変数」に変換されます。環境変数は、単純なキーと値の文字列のペアのみを使用できます。

bashシェルがこのタイプの環境変数を使用して環境を継承すると、その変数が関数であることがわかり、bash適切な名前でその関数をインスタンス化します。

~によるとPOSIX規格:

POSIX.1-2017 シェルのユーティリティおよびユーティリティボリュームは、以下を含む環境変数名を使用します。大文字、数字、および<underscore>_移植可能な文字セットの文字で、数字で始まらない。実装では他の文字を受け入れることができます(MAY)。アプリケーションはそのような名前の存在を許可する必要があります。大文字と小文字は一意のアイデンティティを維持し、一緒に折り畳んではいけません。小文字の環境変数名を含む名前空間は、アプリケーション用に予約されています。アプリケーションは、標準ユーティリティの動作を変更することなく、この名前空間の名前を使用して環境変数を定義できます。

この記事によると、%環境変数を含む名前は許可されていますが/bin/sh、一部のシステム(dashUbuntuやkshOpenBSDなど)で偽装されているような他のシェルは、環境を整理し、明示的に許可された文字を除く名前に含まれるすべての環境変数を削除します。以外の文字。

/bin/shsystem()シェルは、アプリケーションが別のプロセスを開始するために呼び出すときに使用されます。

これはすべて意味するあなたが(Ubuntuに)いて、/bin/sh端末の最後のインタラクティブシェルの環境が呼び出しを介して、または別の方法で(親から子への継承を介して)渡された場合、関数は消えます1dashbashsystem()/bin/sh

解決策~/.bashrc関数は、別名が定義されている場所で定義されます。または、端末にbashログインシェルを作成するようにしてください。

1残念ながら、私はGDMやUbuntuを実行していないので、現在のstraceログインプロセスに関連するプロセスを実行して、実際に何が起こっているのかを確認することはできません。


別のシェルが呼び出されたときに1つのbashシェルと別のシェルの間で消える関数を示す例:bashdash

$ foo () { echo hello; }
$ export -f foo

$ dash -c 'bash -c foo'
bash: foo: command not found

yash機能を削除しない代替例を使用すると、次のようになります。

$ yash -c 'bash -c foo'
hello

同様にksh、OpenBSDでクリーンアップ中に次のことをksh93しないzshでください。

$ ksh -c 'bash -c foo'
bash: foo: command not found
$ ksh93 -c 'bash -c foo'
hello
$ zsh -c 'bash -c foo'
hello

上記の出力のすべての場合において、hello介入シェルは、特に指定された環境変数が関数を形成するという事実を知らない。

$ yash -c 'foo'
yash: no such command `foo'
$ ksh93 -c 'foo'
ksh93: foo: not found
$ zsh -c 'foo'
zsh:1: command not found: foo

おすすめ記事