スクリーンセッション環境変数を更新して、新しいグラフィカルログインを反映しますか?


20

私はLinuxを使用しています。すべてのコマンドライン作業を1つのスクリーンセッション内で行うのが好きなので、端末を失うことなくグラフィカルログインなどを再開できます。ただし、ログアウトしてグラフィカルセッションに戻ると、DBusセッションなどのすべてのセッション環境変数が変更されます。これは、再度ログインした後、スクリーンセッションに古い(および間違った)環境変数が含まれることを意味します。そのため、スクリーンセッションからグラフィカルプログラムを起動しようとすると、せいぜいセッションバスに接続できないという警告が表示されます。最悪の場合、完全に起動しません。

したがって、私が探しているのは、実行中の画面インスタンスの環境変数を変更して、その後作成されるすべての画面ウィンドウが新しい環境変数を継承するようにする方法です。これを行う方法はありますか?


3
あぁ!:私はちょうどこれを見つけるために、画面全体のマンを通じてページングsetenv [var [string]] Set the environment variable var to value string. If only var is specified, the user will be prompted to enter a value. If no parameters are specified, the user will be prompted for both variable and value. The environment is inherited by all subsequently forked shells.
ライアンC.トンプソン

スクリーンへの-Xスイッチを使用してsetenvを呼び出すことができます。残念ながら、現在のシェルではなく、後続のすべてのフォークされたシェルでのみ機能します。
ボリスBukh

現在、byobuには画面とtmuxの両方に対するこのソリューションが組み込まれています。
ライアンC.トンプソン14

回答:


8

screen古い環境を継承するため、セッションからシェルスクリプトを開始できません。ただし、FIFOを使用して、新しい環境変数を古いスクリーンセッションに取り込むことができます。グラフィカルセッションを開始すると、そのfifoを埋めることができます。

#!/bin/bash
FIFO=/tmp/your_variables
[ -e $FIFO ] && cat $FIFO > /dev/null || mkfifo $FIFO

# save number of variables that follow
NVARS=2
echo $NVARS > $FIFO
echo ENV1=sth1 > $FIFO
echo ENV2=sth2 > $FIFO

ログイン時にバックグラウンドでそのスクリプトを開始します(すべての変数が読み取られたときにのみ終了します)。

これで、FIFOから読み取ることができます。たとえば、この関数を .bashrc

update_session() {
  FIFO=/tmp/your_variables

  NVAR=$(cat $FIFO)
  for i in $(seq $NVAR); do
    export $(cat $FIFO)
  done
  #delete the pipe, or it will not work next time 
  rm $FIFO
}

古いscreenセッションでできるように

update_session

ウィンドウのメインシェルを変更するために、実行中のセッションのウィンドウごとにこれを行う必要はありませんか?
いんちきキホーテ

〜quackが言っているように、各シェルを個別に更新する必要があります。
dmckee

そう、あなたはの各シェルでそれをする必要がありますscreen。AFAIK screenは、外部から実行中のセッションと通信するためのソケットなどを公開しません。
ベンジャミンバニエ

@dmckeeですが、もちろんすべての新しい screenセッションにはすでに最近の環境変数があります
ベンジャミンバニエ

今のところ、この答えを受け入れることにしました。これを実際に実装することに慣れたら、更新します。しかし、今のところは、理論的に可能であることを知っているという温かいあいまいな気持ちを持つだけで十分です。
ライアンC.トンプソン

2

これを行うスクリプトを実装しました。ここから入手できます:https : //github.com/DarwinAwardWinner/screen-sendenv

入れた後screen-sendenv.py、あなたの中に$PATH、あなたはあなたの.bashrcに次のコードを使用することができます。

VARS_TO_UPDATE="DISPLAY DBUS_SESSION_BUS_ADDRESS SESSION_MANAGER GPG_AGENT_INFO"
screen_pushenv () {
  screen-sendenv.py -t screen $VARS_TO_UPDATE
}
tmux_pushenv () {
  screen-sendenv.py -t tmux $VARS_TO_UPDATE
}
screen_pullenv () {
  tempfile=$(mktemp -q) && {
    for var in $VARS_TO_UPDATE; do
      screen sh -c "echo export $var=\$$var >> \"$tempfile\""
    done
    . "$tempfile"
    rm -f "$tempfile"
  }
}
tmux_pullenv () {
  for var in $VARS_TO_UPDATE; do
    expr="$(tmux showenv | grep "^$var=")"
    if [ -n "$expr" ]; then
      export "$expr"
    fi
  done
}

これを使用するには、実行するscreen_pushenv前に実行screen -rして、スクリーンセッションに再アタッチします。次に、でアタッチした後screen -r、で既存のシェルの環境を更新できますscreen_pullenv。tmux関数は、画面に似た別の端末マルチプレクサであるtmuxに対して同じことを実現します。


うわー、ライアン、それはたくさんのコードです。以前に受け入れられた回答のどこが悪かったのでしょうか(少なくとも刺激を受けました)。
ベンジャミンバニエ

1
さて、画面(およびtmux)には、画面の現在のウィンドウのシェルではなく、画面自体の環境変数を設定する「setenv」コマンドがあることがわかりました。つまり、スクリプトを使用した後、そのスクリーンセッションで新しく作成されたすべてのウィンドウは、それらのすべてで更新スクリプトを実行することなく、自動的に新しい環境を取得します。もちろん、更新スクリプトは既存のシェルを更新するのに役立ちますが、FIFOから読み取るのではなく、screen / tmuxセッション自体に新しい値を問い合わせるために書き換える必要があります。
ライアンC.トンプソン

あなたは、画面/ tmuxのセッションから現在のシェルの中に変数を引っ張るためにどのように見ることができますここで、screen_updateおよびtmux_update機能。これらのby武に依存しないバージョンで回答を更新します。
ライアンC.トンプソン

1
とにかく、何が間違っていたかについての質問に直接答えるために、あなたの答えは質問にまったく答えず、むしろ関連する質問に答えます。スクリーンセッション内で実行されているシェル内の環境変数を更新する方法を示しますが、スクリーンセッション自体の環境変数を更新する方法は示しません(新しく生成されたウィンドウが新しい値を継承するなど)。それはまだ良い解決策だったので、私はその時に受け入れましたが、私は尋ねられたように私の質問への本当の答えを最終的に実装することを常に意図していました。だから、個人的なものは何もありません。
ライアンC.トンプソン

ねえライアン、答えてくれてありがとう。あなたが言及した今、setenv私はこれがどのように優れているかわかります。リンク先のコードからは明らかではありませんでした。再度、感謝します!
ベンジャミンバニエ

2

あなたは呼び出すことができますsetenv使用することによって、インタラクティブにスクリーンプロセスで環境変数を変更するには、コマンドを:Ctrl- A+ :setenv(注意:画面のコマンドを入力する文字を。)あなたは、環境変数の名前と値の入力を求められます。

(他の回答/コメントと同様に)これは(親)スクリーンプロセスに影響するため、新しく作成されたスクリーンセッションに影響しますが、現在のスクリーンセッションや既存のスクリーンセッションには影響しません。

必要に応じて、環境変数の名前と値を同時に指定できます:Ctrl- A+ :setenv DISPLAY :100。新しいスクリーンセッションのDISPLAYを「:100」に設定します。

環境変数を削除するには、「unsetenv」を使用できます-例Ctrl- A+:unsetenv DISPLAY


0

これはおそらく、より簡単なソリューションです(ユーザーが決定します)。重要な部分は、コマンドが実行さsavedisplayれるたびに関数を呼び出すエイリアスですscreen。コマンドは自動的に実行されないため、~/.bashrcなどの非常に特殊なものの代わりに挿入できます~/.ssh/rc

savedisplay() {
    # Write latest bash display to a file, This is used to 
    # update running bash sessions for a "screen -r"
    echo "export DISPLAY=$DISPLAY" > ~/.XDISPLAY
    echo "export XAUTHORITY=$XAUTHORITY" >> ~/.XDISPLAY
    # This will only update the environment for new windows
    screen -X setenv DISPLAY $DISPLAY
    screen -X setenv XAUTHORITY $XAUTHORITY
}

# run this to update env variable in a running session
updatedisplay() {
    source ~/.XDISPLAY 
}

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