65

プログラムの相乗効果をsshトンネルと一緒に使用しています

それは動作します。コンソールを開いて、次の2つのコマンドを入力するだけです。

ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost

怠惰なため、アイコンを1回クリックするだけで実行されるBashスクリプトを作成しました。

#!/bin/bash
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost

上記のBash-Scriptも同様に機能しますが、今度は1回のマウスクリックでシナジーとsshトンネルを強制終了したいので、後でそれらを強制終了するためにシナジーとsshのPIDをファイルに保存する必要があります。

#!/bin/bash

mkdir -p /tmp/synergyPIDs || exit 1
rm -f /tmp/synergyPIDs/ssh || exit 1
rm -f /tmp/synergyPIDs/synergy || exit 1

[ ! -e /tmp/synergyPIDs/ssh ] || exit 1
[ ! -e /tmp/synergyPIDs/synergy ] || exit 1

ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
echo $! > /tmp/synergyPIDs/ssh
synergyc localhost
echo $! > /tmp/synergyPIDs/synergy

しかし、このスクリプトのファイルは空です。

sshと相乗効果のPIDを取得するにはどうすればよいですか?
(私は組み合わせを避けようとps aux | grep ... | awk ... | sed ...します、もっと簡単な方法がなければなりません。)

4

11 に答える 11

74

簡単な要約:機能しません。

私の最初のアイデアは、PIDを取得するためにバックグラウンドでプロセスを開始する必要があるということです$!

のようなパターン

some_program &
some_pid=$!
wait $some_pid

あなたが必要とすることをするかもしれません...それを除いて、sshはもはやパスフレーズを要求するためにフォアグラウンドにありません。

それでは、結局、何か違うものが必要になるかもしれません。ssh -fおそらく、シェルがとにかくそれを呼び出すことから決して知ることができない新しいプロセスを生み出します。理想的には、ssh自体がそのPIDをファイルに書き込む方法を提供します。

于 2009-11-30T19:57:33.587 に答える
74

pgrep、、などのユーザーに敬意を表して、pkillはるかに優れた方法があります。ps | awk

ps -aux | grep ...プロセスを見つけることに依存している場合は、衝突のリスクがあることを考慮してください。それが起こりそうにないユースケースがあるかもしれませんが、原則として、それは進むべき道ではありません。

SSHは、バックグラウンドプロセスを管理および制御するためのメカニズムを提供します。しかし、多くのSSHのものと同様に、これは「高度な」機能であり、多くの人(ここでの他の回答から)はその存在に気づいていません。

私自身の使用例では、自宅にワークステーションがあり、その上にオフィスの内部ネットワーク上のHTTPプロキシに接続するトンネルを残し、別のワークステーションを使用して、同じ場所にあるサーバーの管理インターフェイスにすばやくアクセスできます。 。これは、自宅から開始される基本的なトンネルを作成する方法です。

$ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
$ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver

これらにより、sshがバックグラウンドになり、トンネルが開いたままになります。しかし、トンネルがなくなった場合、私は立ち往生しています。それを見つけたい場合は、プロセスリストを解析する必要があり、ホームに「正しい」sshがあります(誤って複数のsshを起動した場合に備えて)似ている)。

代わりに、複数の接続を管理する場合は、SSHのControlMasterconfigオプションと、-O制御用のコマンドラインオプションを使用します。たとえば、私の~/.ssh/configファイルに次のようにすると、

host officefirewall colocatedserver
    ControlMaster auto
    ControlPath ~/.ssh/cm_sockets/%r@%h:%p

上記のsshコマンドを実行すると、spoorが残り、~/.ssh/cm_sockets/制御用のアクセスを提供できます。次に例を示します。

$ ssh -O check officefirewall
Master running (pid=23980)
$ ssh -O exit officefirewall
Exit request sent.
$ ssh -O check officefirewall
Control socket connect(/home/ghoti/.ssh/cm_socket/ghoti@192.0.2.5:22): No such file or directory

そしてこの時点で、ハンマー(、、、など)を使用する必要なしに、トンネル(およびSSHセッションの制御)はなくなりkillます。killallpkill

これをユースケースに戻します...

syngergycTCPポート12345で通信するトンネルを確立していますsyngergys。そのために、次のようなことを行います。

~/.ssh/configファイルにエントリを追加します。

Host otherHosttunnel
    HostName otherHost
    User otherUser
    LocalForward 12345 otherHost:12345
    RequestTTY no
    ExitOnForwardFailure yes
    ControlMaster auto
    ControlPath ~/.ssh/cm_sockets/%r@%h:%p

コマンドライン-LオプションはLocalForwardキーワードで処理され、トンネルが確立された後に確実に制御できるように、Control {Master、Path}行が含​​まれていることに注意してください。

次に、bashスクリプトを次のように変更します。

#!/bin/bash

if ! ssh -f -N otherHosttunnel; then
    echo "ERROR: couldn't start tunnel." >&2
    exit 1
else
    synergyc localhost
    ssh -O exit otherHosttunnel
fi

この-fオプションはトンネルをバックグラウンドで処理し、後でトンネルを閉じるためにControlPathにソケットを残します。sshが失敗した場合(ネットワークエラーまたはが原因である可能性がありますExitOnForwardFailure)、トンネルを終了する必要はありませんが、失敗しなかった場合(else)、synergycが起動され、トンネルが終了した後にトンネルが閉じられます。

また、SSHオプションLocalCommandを使用しsynergycてssh構成ファイル内から直接起動できるかどうかを調べることもできます。

于 2014-10-20T16:28:02.403 に答える
21

このスレッドに出くわし、「pidof」Linuxユーティリティについて言及したかったのです。

$ pidof init
1
于 2012-07-04T12:46:17.133 に答える
16

lsofを使用して、ローカルホストのポート12345をリッスンしているプロセスのpidを表示できます。

lsof -t -i @localhost:12345 -sTCP:listen

例:

PID=$(lsof -t -i @localhost:12345 -sTCP:listen)
lsof -t -i @localhost:12345 -sTCP:listen >/dev/null && echo "Port in use"
于 2013-04-11T06:35:06.157 に答える
13

コンソールのwintowを閉じると接続が切断されるため、コマンドの最後に&を追加したくありません...したがって、ps-grep-awk-sed-comboになりました

ssh -f -N -L localhost:12345:otherHost:12345   otherUser@otherHost
echo `ps aux | grep -F 'ssh -f -N -L localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/ssh
synergyc localhost
echo `ps aux | grep -F 'synergyc localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/synergy

(grepをawkに統合することはできますが、今は怠惰すぎます)

于 2009-12-01T13:56:15.340 に答える
9

をドロップする-fと、バックグラウンドで実行され、で実行してeval、自分でバックグラウンドに強制することができます。

次に、を取得できますpid。必ずステートメント&内に入れてください。eval

eval "ssh -N -L localhost:12345:otherHost:12345 otherUser@OtherHost & " 
tunnelpid=$!
于 2012-05-30T13:16:08.203 に答える
4

これは、synergyc(および自分自身をデーモン化しようとする他のほとんどのプログラム)の特殊なケースです。$を使用して!synergycが実行中にclone()syscallを実行し、bashが持っていると思ったもの以外の新しいPIDを与えることを除いて、は機能します。$!を使用できるようにこれを回避したい場合は、synergycにフォアグラウンドにとどまり、バックグラウンドにするように指示できます。

synergyc -f -n mydesktop remoteip &
synergypid=$!

synergycは、自動再起動のような他のいくつかのことも行います。これを管理しようとしている場合は、オフにすることをお勧めします。

于 2012-12-10T21:59:56.880 に答える
3

別のオプションは、pgrepを使用して最新のsshプロセスのPIDを見つけることです。

ssh -fNTL 8073:localhost:873 otherUser@OtherHost
tunnelPID=$(pgrep -n -x ssh)
synergyc localhost
kill -HUP $tunnelPID
于 2012-08-24T21:55:05.843 に答える
3

@ghotiの非常に良い答えに基づいて、追加の構成を必要とせずにSSH制御ソケットを利用する(テスト用の)より単純なスクリプトを次に示します。

#!/bin/bash
if ssh -fN -MS /tmp/mysocket -L localhost:12345:otherHost:12345 otherUser@otherHost; then
    synergyc localhost
    ssh -S /tmp/mysocket -O exit otherHost
fi

synergycトンネルが正常に確立された場合にのみ開始され、トンネル自体はsynergyc戻るとすぐに閉じられます。ソリューションには適切なエラー報告がありませんが。

于 2016-06-29T11:08:08.533 に答える
2

次の行を使用して、ローカルポートにバインドされているsshプロセスを探すことができます。

netstat -tpln | grep 127\.0\.0\.1:12345 | awk '{print $7}' | sed 's#/.*##'

ローカルホストのポート12345/TCPを使用してプロセスのPIDを返します。sshしたがって、からのすべての結果をフィルタリングする必要はありませんps

そのポートがバインドされているかどうかを確認する必要がある場合は、次を使用します。

netstat -tln | grep 127\.0\.0\.1:12345 >/dev/null 2>&1

1バインドされていない場合、または0誰かがこのポートをリッスンしている場合に戻ります。

于 2012-03-03T22:46:44.707 に答える
2

ここには多くの興味深い答えがありますが、SSHのマンページがこの正確なケースを説明しているとは誰も言及していません!TCP FORWARDINGセクションを参照)。そして、彼らが提供するソリューションははるかに単純です。

ssh -fL 12345:localhost:12345 user@remoteserver sleep 10
synergyc localhost

今詳細に:

  1. まず、トンネルでSSHを開始します。そのおかげで-f、接続が開始され、その後、バックグラウンドにフォークされます( sshがバックグラウンドに送信され、トンネルが作成される前にssh ... &; pid=$!次のコマンドが実行されるソリューションとは異なります)。リモートマシンでは実行され、10秒待ってから終了します。sleep 10
  2. 10秒以内に、目的のコマンド(この場合は)を開始する必要がありますsynergyc localhost。トンネルに接続し、SSHはトンネルが使用中であることを認識します。
  3. 10秒経過後、sleep 10コマンドは終了します。ただし、トンネルはまだによって使用されてsynergycいるため、SSHは、トンネルが解放されるまで(つまり、ソケットを閉じるまで)、基盤となる接続を閉じません。synergyc
  4. synergyc閉じられると、トンネルが解放され、SSHが自動的に終了して、接続が閉じられます。

このアプローチの唯一の欠点は、使用するプログラムが何らかの理由で接続を閉じて再度開く場合、SSHは接続が閉じられた直後にトンネルを閉じ、プログラムが再接続できないことです。これが問題である場合は、@ doakの回答で説明されているアプローチを使用する必要があります。このアプローチでは、制御ソケットを使用してSSH接続を適切に終了-fし、SSHがバックグラウンドにフォークするときにトンネルが作成されるようにします。

于 2020-05-02T00:13:27.263 に答える