bash / dash、インタラクティブ/非インタラクティブ、ログイン/非ログインのすべての組み合わせが環境変数を取得できるように、環境変数をどこにエクスポートする必要がありますか?


11

質問の動機は次のとおりです。

UnityデスクトップでUbuntu 12.04 LTS 2を使用しています。.bashrcファイルで、PATH変数にいくつかのディレクトリを追加し、JAVA_HOMEなどのいくつかの環境変数を定義します。端末(bash、デフォルトのシェルを実行)からアプリケーションを起動すると、これはうまく機能しますが、Unityランチャーを使用するいくつかのショートカットでは、#!/ bin / shを使用するように定義されているように見えるアプリを実行します。は/ bin / dashのエイリアスであり、〜/ .bashrcまたは〜/ .profileの内容を取得しません。

これらのショートカットをすべて変更して、/ bin / shの代わりに/ bin / bashを使用して、強制的に.bashrcの変更を反映させることができると思いますが、それは本当にハックに思えます。

Ubuntu 12.04(デフォルト)が/ bin / shを/ bin / dashにエイリアスし、デフォルトのシェルが/ bin / bashである場合、PATHを変更し、必要に応じて環境変数を定義できる単一の場所がありますこれらすべての状況下で存在するために:

  1. 非ログインbashシェルを作成するときはいつでも(端末を単一で使用して)
  2. ログインbashシェルを作成するとき(たとえば、sshを介してリモートでログインするとき)
  3. Unityアプリケーションランチャーを使用する場合(ランチャーが/ bin / shを使用する場合)。
  4. cronジョブが実行されるとき(/ SHELL = / bin / shが/ etc / crontabにある場合)。

私が正しく理解していれば、私はそれを推測しています:

  • (1)/(2)はbashであり、(3)/(4)はダッシュであるため、(1)/(2)と(3)/(4)は異なります。
  • (1)と(2)は、ログインシェルであるかどうかによって、bashがロードすることを選択するファイルが異なるため、異なります。
  • (3)と(4)は異なります。これは、(3)がログインした後のある時点で表示されるためです(したがって、〜/ .profileは、親プロセスの1つがソースとなり、(4)は、ログインしていないため、〜/ .profileは読み込まれません。

(シェルがインタラクティブであるかどうかなど、他の要因も重要であっても私は驚かないでしょう。そのため、おそらく予想もしなかった組み合わせがさらにあるでしょう...私は私の質問を「改善しました」 「その場合。)

私はある時点で、誰かがシェルに依存しない方法(または少なくともダッシュ/バッシュ互換の方法)で環境変数を変更する方法/場所を説明する何らかのガイドを作成したに違いないことを期待します...そのようなガイドを見つけるために適切な検索用語を見つけるようです。

ソリューションまたはソリューションへのポインタは大歓迎です!

更新しました:

  • 明確化:これは、12.04のインストールプロセスで作成されたデフォルトのUbuntuユーザーなので、特別なことは何もありません。それはありませんので、全く何の.bash_profileはありません... .bashrcに、の.bash_history、および.bash_logoutされていない〜/ .profileに(明示的にソースは、〜/ .bashrcのことを)持っている、とだけ〜/ .bash *が存在するファイル。
  • スコープ重視:私は本当にデフォルト対話型シェル(bashの)および(ダッシュにエイリアス)使用/ binに/ SHに起こる任意のスクリプト以外の任意のシェルを気にしないので、何もしてこれを複雑にする必要はありません余分のためには、 tcsh / ksh / zsh / etc。サポート。

2
それを1つのファイルに配置してから、他のrcファイルにソースを任せます。
konsolebox 2013

ここにあるダッシュマンページによると、ログインシェルの$ HOME / .profileを読み取る必要があります。
Etan Reisner 2013

@konsoleboxどのrcファイルですか?AFAICT、ダッシュにはrcファイルがありません。そして、私が述べたように、ダッシュは〜/ .profileの内容を拾っていないようです。

@EtanReisnerはい、そしてこれが問題のポイントです。ダッシュがログインシェルとして実行されていない場合(したがって、〜/ .profileのソースが提供されていない場合)、どうなるでしょうか。

@Mickalotダッシュをインタラクティブに実行していますか?そうでない場合は、それに-lオプションを追加してみてください。
konsolebox 2013

回答:


9

シェルの呼び出しは少し複雑です。bashとdashのmanページにはINVOCATION、これに関するセクションがあります。

要約すると、彼らは言っています(manページに詳細がありますので、読んでください):

When bash is                   | it reads
-------------------------------|----------
login shell                    | /etc/profile and then the first of ~/.bash_profile, ~/.bash_login or ~/.profile that exists.
                               |
interactive non-login shell    | /etc/bash.bashrc then ~/.bashrc
                               |
non-interactive shell          | The contents of $BASH_ENV (if it exists)
                               |
interactive (as "sh")          | The contents of $ENV (if it exists)

-

When dash is                   | it reads
-------------------------------|---------
login shell                    | /etc/profile then .profile
                               |
interactive shell              | The contents of ENV (it it exists, can be set in .profile as well as in initial environment)

他のシェルを使用したことがないので、他のシェルについては知らない。あなたの最善の策は、共通の場所のスクリプトを指すようにいくつかの環境変数を設定し、カバーしないいくつかの場合に手動で(適切な場合)調達することです。


悲しいことに、この問題の核心は、ダッシュテーブルに欠けているものです。Unityデスクトップが#!/ bin / shで始まるスクリプトを呼び出すと、それは(私が想定しているように)非ログイン、非対話型のダッシュシェルを起動します。だから問題は、マトリックスの他の場所にある同じ環境変数をどのように利用できるようするのですか?

正しい。それがbashがそのスロットにBASH_ENVを追加した理由だと思います。ダッシュがそのスロットで機能するように見えないことを考えると、ダッシュを起動するアプリケーションの環境の変更に影響を与えずにその問題を解決できるかどうかはわかりません(ダッシュがそれを継承するなど)。これには、@ Mickalotからの.xsession(rc)コメントが作用するX環境で環境変数を設定する必要があります。これは、彼が示したように、4番目の項目はまだ残されています(ただし、これは実際には多少意図的なものだと思います)。
Etan Reisner 2013

私はUbuntu 12.04 LTSを使用しているため、cronは実際にはpixie-cronなので、crontabファイルでenv変数を定義できます... SHELL = / bin / bashとBASH_ENV =〜/ .bashrcはそれを実行する必要があると思いますか?

3

したがって、これに取り組むにはいくつかの方法があります。多くの人は次のいずれかを行います:

a。すべてのshスタイルのシェルに共通するものを含む1つのファイルを用意します。たとえば、et cetraの.shcommonそれぞれで、.profile .bashrc .kshrcこれをソースとして使用します. .shcommon

b。すべてを入れて.profile、他のファイルからこれを調達します。

特定のシェルまたはインタラクティブシェルと非インタラクティブシェルに必要なものは、ソーシングする前に適切なファイルに入れることができます .shcommon

個人的には、複数のファイルを管理するのは嫌いです。したがって、私は次のアプローチを使用します:

最初に、必要なものはすべて入っ.profile ていますbashとkshに固有のものがいくつかあるので、以下を使用して現在のシェル名を決定します。

# get name of current shell
# strip leading - from login shell
export SHELLNAME="${0#-}"

次に、次のような特定のシェル用のコマンドを含めます(ケースステートメントを好む人もいます)。

if [ "$SHELLNAME" = 'bash' ]
then
    shopt -s checkwinsize

elif [ "$SHELLNAME" = 'ksh' ]
then
    stty erase ^?
fi

対話型シェルでのみ実行する必要があるコマンドがある場合は、次のコマンドを使用します。

# check for interactive flag i in shell options $-
# in bash and ksh you could use the following, but breaks in dash
# if [[ $- == *i* ]]
if [ "$(echo $- | grep i)" != "" ]
then
  fortune
fi

たとえば、すべてのshスタイルのシェルに共通するものPATHは、一番上に配置できます。

次に、シンボリックリンクを使用して、この同じファイルをすべてのshスタイルのシェルにロードします。

ln -s .profile .bashrc
ln -s .profile .kshrc

いくつかの注意点があります。がある.bash_profile場合、bashは代わりにこれをロードしますが.profile、ダッシュとkshは引き続きロードします.profile これは問題の一部である可能性があります。

また、本当にPOSIX互換のスクリプトが必要#!/bin/bash#!/bin/dashない限り、スクリプトでの使用を検討することもできます。bashには、非常に優れた追加機能が多数あります。shはこれらの機能の多くを無効にするため、dashまたはbashが呼び出されます。

また、bashのmanページでは、.profilevs .bashrcが読み込まれるタイミングを説明しています。同様のルールがkshにも適用されます。ダッシュは.profileログイン時にロードされ、ENV環境変数を使用して指定されたインタラクティブシェルの起動時にファイルをロードできます.profile(ダッシュのマニュアルページも確認し、.profileを検索してください)。


シェル名の$ 0をテストできませんか?それが機能しないシェル/ケースはありますか?
Etan Reisner 2013

同様に、$でのiのチェックは、対話型シェルテストでは不十分ですか?(それは私が許可するttyなしでインタラクティブなシェルでトリガーされますが、それは望ましくない副作用かもしれませんし、そうでないかもしれません。)
Etan Reisner 2013

@エタン:ええと、私は最初に試し$0て問題に遭遇したことを知っています...彼らが何であったかを正確に思い出すことができないようです。コンソールに直接ログインすると$0-bashではなくと表示されますがbash、修正できる可能性があります。

@エタン:はい、私がチェックインして$-も機能します。ttyなしでインタラクティブシェルを使用する場合について考えなければなりませんか?あなたの解決策は何らかの理由でそれに対するより良い「感じ」を持っています、私はそれを変更するかもしれません。

手段「ログインシェル」が、はい、あなたは値をテストしたり、誰かにそれを表示したい場所にそのためのアカウントに必要があるだろう。--bash
Etan Reisner 2013

0

ケース(1)と(2)は.bashrcと.profileで環境変数を調達することで解決されるので、実際の問題は、「(3)と(4)で同じ変数を取得するファイルの名前は何ですか。

ありますように見えます質問askubuntuに(私はUnityのデスクトップにインポートされる環境変数を得るのですか)の一部(3)への答えが。/ etc / X11 / Xsessionからソースとなる〜/ .xsessionrcファイルを作成することが提案されています。(私はこれを試しました、そしてそれはうまくいくようです...そうです!)

(4)のために何をすべきか、私はまだ困惑しています。確かに、cronジョブ(またはデーモン)作成する場合、「/ bin / foo」を「bash -i -c / bin / foo」のようなものに置き換えて、bashを使用して適切な環境変数をロードするように強制できますが、これは、私に代わってデーモンタスクまたはcronジョブをインストールする可能性のあるサードパーティツールをいじくり回す必要があることも意味します。ゆく。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.