3

私はUbuntuを実行しており、新しいターミナルウィンドウを開くのと同じ方法ですべての環境を使用できるgnome-terminalように実行したいと考えています。たとえば、パスフレーズなしの ssh を使用します。tmuxgnome-session

問題はプロセス階層のようです...

の新しいウィンドウgnome-terminal:

$ pstree -ps $$
init(1)───lightdm(1825)───lightdm(18486)───gnome-session(18552)───gnome-terminal(18626)

新しい セッションに入るとtmux(上記のターミナルウィンドウでも:

$ pstree -ps $$
init(1)───tmux(15798)───bash(21770)

tmuxinit の直接の子であり、セッションのプロセス階層にはないようです。の子として作成する方法はありgnome-sessionますか?

編集:以下の素晴らしい答え(受け入れられたもの)!ただし、tmux のすべての子 bash プロセスを最新の環境に更新するための回答を受け取ったので、私が書いた関数を含めようと思いました。

#!/bin/bash

tmup () 
{ 
    echo -n "Updating to latest tmux environment...";
    export IFS=",";
    for line in $(tmux showenv -t $(tmux display -p "#S") | tr "\n" ",");
    do
        if [[ $line == -* ]]; then
            unset $(echo $line | cut -c2-);
        else
            export $line;
        fi;
    done;
    unset IFS;
    echo "Done"
}
4

1 に答える 1

4

tmuxサーバーは、daemon(3) を呼び出してそれを開始したプロセス (つまり、最初のtmuxクライアント) から自分自身を切り離します。これはオプションではないため、サーバーは常にデーモン (3)によって実行される二重フォークと中間終了の後に PID 1 (たとえばinit ) に再親化されます。

一般に、 tmuxサーバーが(生き残った) プロセスの親子関係を介してgnome-sessionに直接「接続」されなくなったことは重要ではありません。

sshの場合、パスフレーズを再入力せずにキーを使用できるかどうかは、ssh-agentプロセスへのアクセスに依存しています。sshのインスタンスは、SSH_AUTH_SOCK 環境変数を探して、キーを提供できるssh-agentに連絡する場所を認識します。gnome-sessionは、おそらくssh-agentを開始し、その環境に適切な SSH_AUTH_SOCK 値を入力するように手配します。この環境は、さまざまなプロセスが開始されると、親から子に継承されます。このようにして、tmuxサーバーは SSH_AUTH_SOCK 値も継承します (シェルから取得した最初のtmuxクライアントから)。gnome -sessionから取得したgnome-terminal )。

ただし、別の環境から開始されたtmuxセッションにアタッチすると、問題が発生します。tmuxサーバーの PID がgnome-sessionの PIDよりも低いという事実によって示唆される、次のシナリオを検討してください。

  1. GUI セッションにログインします。
    gnome-sessionssh-agentSSH_AUTH_SOCK=fooを開始し、その環境で構成します。この値は、将来のすべての子に継承されます。
  2. (シェルとgnome-terminalを介して) tmuxサーバーを起動します。tmuxサーバー は継承します。その子 ( tmuxセッションで実行されているシェルなど) に渡されます。
    SSH_AUTH_SOCK=foo
  3. tmuxセッションから切断し、GUI セッションからログアウトします。tmuxサーバーと
    そのは.SSH_AUTH_SOCK=foo
  4. その後、GUI セッションに再度ログインします。
    今回はgnome-sessionがそれを設定SSH_AUTH_SOCK=barし、その子に渡します。
  5. tmuxセッションに再接続します。
    この時点で、tmuxSSH_AUTH_SOCK=barの「外側」とセッションの「内側」があります。これはおそらく問題に遭遇する場所です。SSH_AUTH_SOCK=foo

事実上、tmuxサーバーは元の GUI セッションよりも長く存続しているため、最初に継承した、そのセッションに固有の環境変数は無効になる可能性があります (次回 GUI セッションにログインしたときにまったく同じ値を使用しない限り)。

幸いなことに、tmuxにはこのシナリオを処理するための機能があります。セッション オプションはupdate-environment、クライアントがセッションを作成または接続するときに「セッション環境」にコピーされる (またはセッション環境から削除される) 環境変数のリストを指定します。SSH_AUTH_SOCK はこのオプションのデフォルト値の一部であるため、再接続すると更新されます。ただし、tmuxはその「セッション環境」 (そのセッションの新しい子によって継承される) しか更新できません。

残念ながら、tmuxには、そのセッションの一部である既存のプロセスを更新する方法がありません(実際、実行中のプロセスの内部をいじることができるデバッグ ツールがなければ、これは不可能です)。そのため、上記のシナリオの後にウィンドウ/ペインで実行されている既存のシェルは、無効な SSH_AUTH_SOCK を使用している可能性があります。sshは無効な値について文句を言うことはありません。適切なキーのパスフレーズを要求するだけです。

次のようなコマンドを使用して、セッション環境から SSH_AUTH_SOCK の値を抽出し、古いセッションから既存のシェルに組み込むことを試みることができます。

 SSH_AUTH_SOCK=$(tmux show-environment | awk '/^SSH_AUTH_SOCK=/ { sub(/.*=/,""); print }')

他の環境変数に関連する問題がある場合は、別のコンテキストから再アタッチした後、それらをupdate-environment(たとえばset-option -ga update-environment ' FROBNIZ'~/.tmux.conf) 追加し、同様の操作を行って既存のシェルに値をコピーする必要がある場合があります。

于 2013-01-30T08:07:37.457 に答える