GNU Screenは10.5.8で私のPATHを継承しません


11

端末のニーズに合わせて日常的に画面を使用していますが、とても満足しています。最近では、しかし、私は私のbashの設定ファイルにいくつかの更新をしたと私は、さまざまな設定をしていることに気づいPATH(要素をPATHMANPATHINFOPATH2ヶ所で、など)。私はファイルを本来あるべき姿に変更し、今ではすべての環境変数が一度に設定され.bash_profileます。ここに私の問題があります。

どうやら、私が2か所に設置したのは画面のせいでした。screenは実行するだけのように見え、元のbashシェルから自分や他の環境変数を正しく継承しているように見え.bashrcませPATH。これは実行するだけで.bashrc、変数を設定する.bash_profileだけなので、不完全なを取得しPATHます。

私の質問は、環境変数を重複せずに画面に表示する方法です。Bashドキュメントを読むと、画面がログインに使用するシェルの種類、つまり非ログインインタラクティブシェルである可能性があることが示されているようです画面に特定の種類のシェルを強制的に使用する方法を理解できませんでした。を介して使用するシェル-s /bin/bash

私のGitHubページで私の設定ファイルを熟読できますこれは画面を壊したコミットコミットです

編集:私は使用Screen version 4.00.03 (FAU) 23-Oct-06していて、それを呼び出す傾向がありますscreen -h 50000

編集: Cygwin(CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686Screen version 4.00.03 (FAU) 23-Oct-06)でこれをテストできるようになりました。Macとは異なる動作を示します。

私が今発見した特定の動作は、Cygwin PATHで.bash_profileに加えた変更が画面に入ったときに複製され、画面ウィンドウを連続して作成してもパスは複製されず、.bash_profileが再ソースされることです。

私が話している動作を説明するために:

新しいターミナルからの出力:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

画面の最初の呼び出しからの出力:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

以降の呼び出しC-a c

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

あなたは見ることができます


重複は、「ログイン」シェルである無条件にこれらのエントリを追加するようにbashを構成しており、「ログイン」シェルとしてbashを呼び出すようにscreenに指示しているためです。シェル、画面、環境変数の一般的な問題に対処するために、回答を書き直しました。
Chris Johnsen、2010年

回答:


16

画面と環境変数

デフォルトでは、画面はセッションが開始されたときの環境変数に関係なく、シェル(および他のプロセス)に渡されます(つまり、再接続しても、新しいシェルに与えられる環境変数は変わりません)。しかし、画面とシェルの両方の構成ファイルは一般に環境変数を変更するため、予期しない変更が発生する可能性のある場所がたくさんあります。TERMのように、画面を変更する変数はほとんど常にありますが、これらの変数は通常、画面が提供する機能に必要です。

シェルの設定もscreenの設定もFOOBARという名前の変数を変更しないとしましょう(かなり可能性が高いので、全体として)。でセッションを開始するとFOOBAR=foo screen、そのセッションで作成されたすべてのシェルには、値がのFOOBARという名前の環境変数がありますfoo

画面またはシェルが変更する可能性のある変数については、状況はさらに複雑になります。

画面を使用しているときに不足している設定

ログインシェル

screenによって起動されたシェルで一部の設定が見つからない場合は、シェルが「ログイン」シェルの設定を更新するようにのみ構成されていることが原因である可能性があります。ほとんどのシェルは**argv == '-'画面を使用するように構成できる特別な規則(C:で)を理解しています。

画面のドキュメントごと:

シェル コマンド

新しいシェルの作成に使用するコマンドを設定します。これにより、環境変数$ SHELLの値が上書きされます。これは、$ SHELLで指定されたプログラムの実行を期待しているtty-enhancerを実行したい場合に役立ちます。コマンドが「-」文字で始まる場合、シェルはログインシェルとして起動されます。

持っているために、スクリーン、「ログイン」シェルとして起動シェルを起動し、画面をscreen -s -/bin/bashたり、あなたに次の行を追加します.screenrc

shell -/bin/bash

使用しているシェルへのパスを調整します。

画面構成

欠落またはリセットの環境変数もが原因である可能性setenvunsetenvのコマンド画面の設定ファイル。ホームディレクトリの.screenrcと、画面のコンパイルで「システムscreenrc」として使用しているファイルの両方を確認する必要があります(strings "$(which screen)" | fgrep -i screenrc通常、コンパイル時に構成されたパス名を検索するようなコマンドを試してみてください/システムにインストールされた画面の場合はetc / screenrc、アドオンのインストールではおそらく他のパス名が使用されます)。を使用SCREENRC=/dev/null SYSSCREENRC=/dev/null screenしてこれらの設定ファイルを一時的に回避できますが、SYSSCREENRCの効果的な使用を妨げるコンパイル時オプションがあります (おそらく、システム管理者が少し初期設定を強制できるようにするためです)。

画面使用時の設定の重複

シェルの構成ファイルのPATHなどの環境変数に項目を追加して、更新された値を通常のシェルセッション(xtermまたは他のターミナルウィンドウ、コンソールセッションなど)で使用できるようにすることは、ごく一般的です。そのようなアイテムがシェルのシェルごとの構成で追加された場合(または、-/path/to/shell上記の設定を使用して、ログインごとのシェル構成で追加された場合)、screenによって起動されたシェルには、追加されたアイテムの複数のコピーが含まれる可能性があります。

これを回避する1つの方法は、シェルのログインごとの構成にPATHなどの変数へのすべての追加を置き-/path/to/shellscreenでシェル設定を使用しないことです。

別の戦略は、変数に新しい項目のみを条件付きで追加することです。シェルによっては、これを行うコードは少し複雑になる場合がありますが、通常は簡単に使用できるようにシェル関数にカプセル化できます。

さらに別の戦略は、常に設定ファイルの固定値から始めることです。これにより、デフォルト値が大幅に異なる場合に、システム間で構成ファイルを移動するときに問題が発生することがあります。

診断

特定の変更が発生している場所を直接見つけることができない場合は、次の操作を実行して、変更が発生している場所を追跡できます。

初期シェルの現在の値を確認します。

echo "$PATH"

サブシェルが作成されたときに、シェル自体が値をどのように変更するかを確認します。

/bin/bash -c 'echo "$PATH"'

「ログイン」サブシェルが作成されたときにシェルが値を変更する方法を確認します。

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

画面で値がどのように変更されるかを確認します

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log

これは私の問題の一部を解決します。残念ながら、それは完全には行きません。現在、screenは正常に動作しscreen -s -/bin/bashていますが、私の作業マシンのCygwinで動作するようになっているため、動作しません。そのマシンで実行するscreen -h 50000と、PATH実際にファイルを再度ソースすることなく、単純に継承されます。これは、新しいウィンドウを開くたびに実行されます。
Tim Visher、

スクリーンプロセスの環境は、その子プロセスによって常に継承される必要があります(TERMのようなものはオーバーライドする可能性があります)。試してみてくださいFOOBAR=baz screenチェックecho $FOOBARからシェルウィンドウにscreenscreen -s -/bin/bash。両方のバリエーションにはFOOBAR=が必要bazです。PATH変更されている場合は、何が行われているかを追跡する必要があります。試してみてくださいSYSSCREENRC=/dev/null SCREENRC=/dev/null screen。それがうまくいく場合PATHは、おそらくsetenv PATHin /etc/screenrcまたは~/.screenrcです。そうでなければ、それはあなた.bashrcがやっていることです。
Chris Johnsen、2010

私は私の答えの大規模な書き換え/追加を行いました。
Chris Johnsen、2010年

2

前回同様の問題を目にしたのは、screen -l起動時の画面で解決しました。

-l呼び出し時にオプションを使用してscreenログインモードをオンにし、のdefloginおよびloginコマンドで制御する.screenrc)、画面がデフォルトでウィンドウにログインするかどうかを設定できます(/ etc / utmpエントリの追加/削除)。

ログインモードはデフォルトでオンになっていますが、コンパイル時に変更できます。画面がutmpサポートでコンパイルされていない場合、これらのコマンドは使用できません。

-lDebian Lennyのデフォルト画面(v4.0.3)のモードは必要ないようです。デフォルトではオンになっているようです。私~/.profile~/.bashrc正しく読まれています。どのように呼び出しscreenますか?どのバージョンを使用していますか?


この理論の下でscreen -ln、を実行すべきではありません~/.profile。それでも実行されます。だから-lフラグを試してみてください、しかしこれはおそらく正しい答えではありません。とりあえずここに置いておきます。
quack quixote、

ファイルにエントリを追加-lするかどうかscreenを制御するだけutmpで、独自の-lオプションで新しいシェルを呼び出すか、exec-with- --prefixカスタムを使用するかは制御しないようです。
Chris Johnsen、2010


1

.bash_profile内から.bashrcを調達しても問題はありません。マシンをローカルでのみ使用している場合、.bash_profileは、ほとんどの場合、最初のログインを行ったときにのみ読み込まれます(他の場合は明らかに読み込まれます)。

ログイン時にのみ何かを実行したい場合は、情報を.bash_profileに入れ、それ以外はすべて.bashrcに入れるようにファイルを整理します。PATHは.bashrcに入れたものの1つであり、.bash_profileで.bashrcを取得します。


.bashrc.bash_profileファイルをどこかに投稿して、私がそれらを見ることができるようにしますか?同様のことをしているときに遭遇した問題はPATH、新しい画面インスタンスを作成するたびに大きくPATHなり、古いものを継承してすべてを再度追加するためです。
Tim Visher、2010

申し訳ありませんが、ティム、見当たりませんでした...私は周りの多くのことを変更したので、あまり意味がありませんが、これは基本的に私がやっていることです。#.bash_profile if [-f〜/ .bashrc]; その後。〜/ .bashrc fi次に、他のすべてを.bashrcに入れます。ただし、最初にログインしたときに開始したいものを除き、.bash_profileに入ります。PATHは.bashrcで1つのパス定義ではなく一連の行として処理されます。ほとんどの場合、export PATH = / path / to / binaries1:$ PATH export PATH = / path / to / binaries2:$ PATH

0

私は、ファイルを作成しているように私はいくつかの問題を抱えているときはいつでも$HOME/.debugして、すべてのファイル(例えば、ログイン/シェル起動時に実行/調達~/.bashrc~/.bash_profile~/.profile/etc/bashrc、など)私は最初の行として持ちます

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

または類似。特定のデバッグについては、次のようなものを追加することもできます

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

このようにして、どのファイルが使用されているか、または使用されていないかを100%確実に確認できます。

stderrへのリダイレクトは重要です。多くの状況でstdoutを混乱させるようなことはしたくないでしょう。


0

システムはbashrcに触れないため(グラフィックセッションのように)、. profileをそのまま使用できます。これで、2つの異なる環境のセットができます。1つは.profileから、もう1つは.bashrcからのbashです。

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