web-dev-qa-db-ja.com

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

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

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

これらのショートカットをすべて変更して、/ bin/shの代わりに/ bin/bashを使用して、.bashrcの変更を強制的に取得できると思いますが、それは本当にハッキーなようです。

Ubuntu12.04(デフォルト)が/ bin/shを/ bin/dashにエイリアスし、デフォルトのシェルが/ bin/bashであるとすると、PATHを変更し、必要に応じて環境変数を定義できる場所が1つあります。これらの状況のallの下に存在すること:

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

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

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

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

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

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

更新しました:

  • 明確化:これは12.04のインストールプロセスによって作成されたデフォルトのUbuntuユーザーであるため、特別なことは何もありません。 does〜/ .profile(明示的に〜/ .bashrcをソースする)があり、存在する〜/ .bash *ファイルは.bashrc、.bash_history、および.bash_logout ...だけです。 .bash_profileはありません。
  • スコープの強調:デフォルトのインタラクティブシェル(bash)と/ bin/sh(ダッシュと呼ばれる)を使用するスクリプト以外のシェルはあまり気にしないので、これを何かで複雑にする必要はありません- extra tcsh/ksh/zsh/etcの場合。サポート。
11
Mickalot

シェルの呼び出しは少し複雑です。 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)

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

9
Etan Reisner

したがって、これにアプローチする方法はいくつかあります。多くの人は次のいずれかになります。

a。すべてのshスタイルのシェルに共通するものを含む1つのファイルを用意します。たとえば、.shcommonと、各.profile.bashrc.kshrcなどで、これを. .shcommonで調達します

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

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

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

まず、必要なものはすべて.profileに入ります。bashとkshに固有のものがあるので、次を使用して現在のシェル名を決定します。

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

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

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

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

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

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

いくつかの補足事項として、.bash_profileがある場合、bashは.profileの代わりにこれをロードしますが、dashとkshは.profileをロードします。これは問題の一部である可能性があります。

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

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

3
idfah

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

askubuntuに質問のパート(3)への回答(Unityデスクトップにインポートする環境変数を取得するにはどうすればよいですか) のようです。/etc/X11/Xsessionによって供給される〜/ .xsessionrcファイルを作成することをお勧めします。 (私はこれを試しました、そしてそれはうまくいくようです...イェーイ!)

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

0
Mickalot