sshを使用して、終了せずにリモートマシンでコマンドを実行するにはどうすればよいですか?


29

通常、次のようにコマンドをsshに渡すと

ssh me@example.com 'some-command.sh'

非対話型セッションを取得し、コマンド(またはスクリプトなど)が実行されるとすぐにsshが終了します。対話型セッションを取得し、ローカルマシンから指定したコマンドを実行する方法を教えてください。たとえば、画面を開いて特定の画面セッションを再開できるようにしたいと思います。

ssh me@example.com 'screen -r 12345'

ただし、これは許可されず、「端末に接続する必要があります」というエラーが返されます。これは本質的に「このコマンドを対話型シェルから呼び出す必要がある」ことを意味すると推測します。

別の例として、仕事で大量のマシンを使用していますが、特定のことを行うために共有アカウントを使用する必要があることがよくあります(ええ、わかっています:悪い考えですが、私を責めないでください方法)、および彼らは通常、デフォルトのシェルとしてkshを持っています。ログインし、bash(またはzsh)に切り替えて、自分のアカウントの.bash_profile(または.zshrc)を取得したいと思います。インタラクティブなsshセッション確立し、ログイン時に実行するコマンドをリモートマシンに渡すことができれば、これは簡単です。

私は投稿することを念頭に置いて非常に巧妙な(そしてテストされていない)ソリューションを持っていますが、誰かがより良い方法を知っていることを望んでいます。

更新:これに気付いていない人のために、私はこれをすべて手作業で行うつもりはないので、対話型セッションを開いてから手作業で行うように言っても、実際には何も解決しません。

2回目の更新:明確にするためにもう一度試みます:サーバー(プログラムでクライアントで指定)で(任意の)コマンドを実行しようとしていますが、それらのプログラムコマンドで行われた操作の影響を受ける対話型セッションを開いています。


echo "command" | ssh user@remote_host
laggingreflex

2
質問の「終了しない」部分を見逃しましたか?コマンドが終了した後、これが終了すると確信しています。
iconoclast

回答:


26

次のコマンドを試して、sshでbashを起動し、独自のプロファイルを取得できます。

ssh  -t hostname "bash --rcfile ~user/.bashrc"

4
+1。この-tスイッチは、質問者の問題も修正screenします。
パッチ

3
接続を閉じずに、これを任意のコマンドで使用できますか?しようとするとssh -t www.dev "echo 'hi there'"、コマンドが実行された直後に接続が閉じられます。
iconoclast

11

dogbaneの答えに基づいて、完全なソリューションは次のようになります。

ssh -t user@server 'cd /a/great/place; bash'

ここ-tでは、インタラクティブシェルに必要な擬似端末の割り当てを強制するために使用します。次に、サーバー上で2つのコマンドを実行します。まず、対話型シェルを開く前に実行したいこと(この場合、ディレクトリを特定のフォルダーに変更します)、次に対話型シェル自体です。bashは、擬似端末があることを認識し、対話的に応答します。

単一引用符は、デフォルトのシェルによって実行されるコマンドとしてすべてがリモートサーバーに渡されることを保証します。

必要な手がかりを提供してくれたdogbaneに再び感謝し-tます。私はこの問題をを使って解決していましたexpect。これは間違いなく大砲でマウスを殺します。(:


2

この解決策を試してください。

echo "command" | ssh user@remote_host

ログインは対話型であり、コマンドは、対話型コマンドラインで入力したかのように渡されます。入力したかのようにセッションが終了します

ssh user@remote_host 'command'

3
コマンドの完了後にセッションが終了した場合、これは質問に答えませ。コマンドの要点は、単にコマンドをサーバーに送信するだけでなく、コマンドの実行後に対話型セッションを残すことsshです。
iconoclast

これは、少なくともコマンドを実行するために、独自のbashファイルを使用せずに、対話をシミュレートするのに適してい-tます。+1
laggingreflex

0

termIOコマンドを使用するには、ssh -Xを使用します。

また、「ssh 'source〜/ .bashrc && cd && do'」のようなコマンドを連鎖させることができます


しかし、チェーン全体が完了した後、インタラクティブセッションが残っていませんよね?まだ閉じますよね?
iconoclast

また、termIOソリューションについて詳しく説明しますか?
iconoclast

0

リモートシステムにdetachをインストールして使用するのはなぜですか

ssh -t user@example.com "/home/user/bin/detach ls"

これは「ls」を実行し、その後、インタラクティブなセッションを残しますか?「ls」の代わりに「source .somefile」を実行して、いくつかのエイリアスと関数を取得したらどうなるでしょう。それらは私のインタラクティブセッションで利用可能になりますか、それとも別のセッションで実行されますか?
iconoclast

いいえ、のためにdetachlsオープンセッションを保持していないとの出力を印刷せずに切断されますlsが、それはまだ実行されます。
ダンD.

サーバー(プログラムでクライアントで指定)で(任意の)コマンドを実行しようとしていますが、それらのプログラムコマンドで行われた操作の影響を受ける対話型セッションを開いています。だからあなたを正しく理解していれば、これは私を助けません。
iconoclast

0

laggingreflexの答えは近いです...私は次のように変更します:

echo "command\n$(cat -)" | ssh user@remote_host

残念ながら、「cat」はstdoutに書き込む行をバッファリングするため、動作方法が気に入らない可能性があります。「echo-cat」という名前のスクリプトを作成すると、次のようになります。

{
  echo "${@}"
 #cat buffers & won't flush to stdout immediately
 #cat -
  IFS='\n'
  while read line
  do
        echo "${line}"
  done
}

バッファリングなしで同じ結果が得られます。

echo-cat "command" | ssh user@remote_host

それはおそらくあなたをあなたの目標にずっと近づけるでしょう...


0

これは見苦しくて、テストされていませんが、うまくいくと思います。

user @ host引数の後に引用符付き引数をとる(たとえば)remote-starterという名前のスクリプトを作成します。

remote-starter user@example.com 'some-command.sh arg1 arg2'

このスクリプトは、最初に引用符で囲まれたコマンドを(たとえば).onetimeリモートマシン上の(たとえば)という名前のファイルに保存し、次に通常のsshコマンドを実行します。今回はリモートマシンで実行するコマンドを渡しません。(スクリプト内からssh user@example.comを実行している場合、exec ssh user@example.comを実行すると動作する場合があります。)

これが機能するためには、リモートマシンが.onetime.bash_profileまたは.zshrcなどからソースを取得する必要があります。を実行した後.onetime、削除する.onetime必要があります。したがって、通常のログインを行ったときにファイルは実行されません。

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