sshとsshを使用したシェル:終了方法


22

次のように、SSHを介して遠隔スクリプトを起動しています。

ssh user@ipaddress '~/my_script.sh'

すべては順調に進んでいますが、スクリプトが終了すると、接続は閉じられません。現在の接続を解除するには、CTRL-Cを押す必要があります。

「〜/ my_script.sh」で「exit」コマンドを試しましたが、役に立たないです。「〜/ my_script.sh」で「ログアウト」コマンドを実行しようとすると、メッセージが表示されます。

logout: not login shell: use exit

...

スクリプトが完了したら、SSHを自動的かつ適切に閉じる方法はありますか?

(明確化のための修正:)ここに私のスクリプトの中にあるものがあります:

#!/bin/sh
path_sources_qas=/sources/QuickAddress/
path_qas_bin=/usr/bin/qas

umount_disque_qas()
{
  # Umount du disque 'qas' s'il n'avait pas été 'umount' :
  nom_disque_monte=`cat /etc/mtab | grep qas | awk '{ print $2}'`
  if [ "$nom_disque_monte" != "" ]
  then
    echo "For safety, umount : $nom_disque_monte"
    umount $nom_disque_monte
  fi

}

# Umount twice (we never know if a st***d guy mounted it twice) :
umount_disque_qas
umount_disque_qas

echo "--------------------------------"
echo "Install ISO quick address..."
nom_fichier_iso=`ls -t $path_sources_qas | awk '{if (NR==1) {print $1}}'`
echo "Mount disk $nom_fichier_iso..."
mount -o loop -t iso9660 $path_sources_qas/$nom_fichier_iso /mnt/qas
echo "Done."

# All the folders are like this :
# /usr/bin/qas/Data.old.10
# /usr/bin/qas/Data.old.11
# /usr/bin/qas/Data.old.12
# ...

echo "--------------------------------"
echo "Stopping QuickAdress server..."
cd $path_qas_bin/apps/
./wvmgmtd shutdown qaserver:2021
sleep 3
echo "Done."

# Get last number of the folder:
num_dernier_dossier_backup=`ls -Atd $path_qas_bin/Data.old* | awk '{if (NR==1) {print $1}}' | awk -F . '{print $NF}'`
# Add 1 :
let "num_dernier_dossier_backup += 1"
# Full name :
nom_dossier_backup=Data.old.$num_dernier_dossier_backup
echo "--------------------------------"
echo "Saving Data to $nom_dossier_backup..."
cd $path_qas_bin
mv Data $nom_dossier_backup
echo "Done."


echo "--------------------------------"
echo "Copying new folder Data..."
cd $path_qas_bin
cp -r /mnt/qas/Data .
echo "Done."

echo "--------------------------------"
echo "Deleting unused datas..."
cd $path_qas_bin/apps/
rm -f $path_qas_bin/Data/frxmos.dap
echo "Done."

echo "--------------------------------"
echo "Restart server..."
cd $path_qas_bin/apps/
./qaswvd &
sleep 3
echo "Done."
sleep 3

echo "--------------------------------"
echo "Check: server state: you should read 'OK':"
./wvmgmtd srvlist
echo "Done."

echo "--------------------------------"
echo "Check: active licences (only one here):"
./wvmgmtd licencelistread qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: counters: number of addresses left:"
./wvmgmtd counterinforead qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: Datasets avalaibles:"
./wvmgmtd datalistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: "meters" for "licence by click":"
./wvmgmtd meterslistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Removing virtual disk..."
umount_disque_qas
echo "Done."

echo "All done"
echo "Click 'Ctrl-C' to quit."

exit

SSHを介して起動すると、実行され、最後に「すべて完了」と表示されます。したがって、これは最後の2行に到達することを意味ます。

自動的に閉じて広報するために私ができる方法


1
スクリプトには何が含まれていますか?
イグナシオバスケス-アブラムス

@Olivier:ポート(エージェントとXを含む)を転送しますか?コマンドが終了し、すべてのTCP接続が閉じられると、ssh接続が閉じられます。
ジル「SO-悪であるのをやめる」

@Gilles:いいえ、スクリプトを実行するためにシェル接続を作成するだけです。何も転送されません。
オリビエポンス

1
@Olivier:を持っている場合は、~/.ssh/configそれなしで試して、オプション-a -x(およびno -o)を渡して、ssh転送が行われないようにします。それでも機能しない場合は、スクリプトの内容を表示します。
ジル「SO-悪であるのをやめる」

@Olivier:スクリプトは、待機中のバックグラウンドジョブを開始しますか?残念ながら、sshスクリプトの場合、ジョブは何も返さないようです。例:ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'ファイルをリストし、表示を完了し、10秒待ってから戻ります。
asoundmove

回答:


19

シェルではなくスクリプトから終了するため、シェルスクリプトの終了は機能しません。スクリプトの完了後にシェルを終了するには

ssh user@ipaddress '~/my_script.sh && exit'

これにより、スクリプトが実行され、シェルが終了します。


3
終了するはずです。スクリプトシェルです。
追って通知があるまで一時停止します。

@デニス:それは彼のために働いていないので、これは代わりに働くかもしれません。
ワッファー

2
@氏。Man:コマンドは元のコマンドと同等ですが、sshd実行中のシェルと実行中のシェルの間に強制的にシェルが存在する点が異なりmyscript.shます。exitあなたは時にスクリプトが終了助けない、行動します書きました。ソリューションが機能する唯一の方法sshdは、親がシェルの場合にスクリプトが奇妙なことを行い、親がシェルの場合にその奇妙なことを行わない場合です。
ジル「SO-悪であるのをやめる」

どうして役に立たないのですか?終了すると、シェルが閉じて接続が終了しますか?そして、これはポスターがしたいことではないでしょうか?
ワッファー

3
@MrMan:~/my_script.sh && exit終了するとすぐに~/my_script.sh終了します。シェルスクリプトが終了しない場合、コマンドはexitとにかくビットに到達しません。だから役に立たない。
ジル 'SO-悪であるのをやめる

12

まだ使用している他のプロセスがある場合、ssh(ここではシェル)によって開始されたプロセスが終了しても、ssh接続は開いたままになります。sshデーモンが従う正確なルールはわかりませんが、少なくとも、子プロセスの標準出力がまだsshによって提供される元のパイプに接続されている場合、接続は使用中です。比較する:

ssh somehost 'sleep 5 &'  # exits after 5 seconds
ssh somehost 'sleep 5 >/dev/null &'  # exits immediately seconds

デーモンを起動するときは、デーモンをバックグラウンドにしてファイル記述子を閉じる必要があります。少なくとも、これを使用します:

./qaswvd </dev/null >/dev/null 2>/dev/null &

nohup前に追加することもできます。ここでは違いはありませんが、スクリプトが端末から実行された場合に役立ちます。デーモンとして機能するように設計された多くのプログラムには、フォークする、ファイル記述子を閉じる、シグナルを無視するなどのコマンドラインオプションがあります。qaswvdドキュメントがある場合は、ドキュメントを確認してください。「デーモン」ユーティリティを調べることもできます。


同じ問題があり、これは機能します。受け入れられた答えは機能しません。
アンディ

5

同じ状況の解決策をグーグルで検索したときに、この投稿を見ました。@Oliverの問題を解決するのは少し遅れていますが、受け入れられた答えは明らかにOPまたは私には機能していなかったので(なぜ受け入れられたのかわかりません)、私はまだ将来のグーグルのために独自のソリューションを投稿したいと思います。簡単です:コマンドに-fオプションを追加しますssh

ssh -f user@ipaddress '~/my_script.sh'

編集

-fオプションの効果はsshバックグラウンドに置くことなので、オプションを追加しなくても、接続が切断されているように見えても、接続がまだ生きている可能性があります。興味があれば、このサイトの別の投稿にある回答を参照することもできます。


注意:元のスクリプトにユーザー入力のプロンプトがある場合、この(-f)は機能しません。
madD7

3

イグナシオのように、私はあなたの台本に何があるのか​​知りたいです。

おそらく、エラー条件を生成する可能な限り最小の例にスクリプトを縮小してみてください。

または、空のスクリプトから開始し、問題が見つかるまで一度にコマンドを追加すると、スクリプトがロックする原因となるコマンドがわかります。

空のスクリプトが原因で問題が発生する場合、sshの構成を調査することをお勧めします。たとえば、.bash_logoutまたは問題を引き起こす可能性のある終了時に呼び出されるものです。


ご提案ありがとうございます。質問にスクリプトのサンプルを追加しました。
オリビエポンズ

@Olivier:スクリプトの無関係な部分だけを追加しました。読者が問題再現できるようにするスクリプト(および必要に応じて使用手順)を投稿します。スクリプトを可能な限り簡素化しますが、それ以上は行いません。
ジル「SO-悪であるのをやめる」

@Gillesありがとう。質問を修正し、スクリプト全体を追加しました。お役に立てれば。問題は、私がバックグラウンドプロセスを起動しているという事実かもしれません(行 "./qaswvd&")。これが問題の原因になりますか?
オリビエポンス

1
@Olivier:はい、メインプロセスはバックグラウンドプロセスが停止するのを待ってから終了します。終了後も何かを実行し続けたい場合は、nohupを試してください。ただし、sshで動作するかどうかはわかりませんが、試してみてください。
asoundmove

2

スクリプトでジョブを使用する可能性があります。その場合、シェルはジョブが終了するのを待ち、それ自体を切り離したくありません。

再投稿するつもりはありません。http://en.wikipedia.org/wiki/Nohup#Existing_jobsを転送します


質問を修正し、スクリプト全体を追加しました。お役に立てれば。問題は、私がバックグラウンドプロセスを起動しているという事実かもしれません( "./qaswvd&"という行)。正しい場合、これが問題の原因である可能性がありますか?
オリビエポンス

バックグラウンドプロセスが問題ですがnohup、サーバー側に端末がないため、ここでは直接問題ではありません。犯人は具体的にはオープンファイル記述子だと思います。
ジル 'SO-悪であるのをやめる'

はい、私はそれが問題だと思います、あなたはそれをコメントするか、上記のリンクからハックを適用しようとすることができます
オレシィ


0

問題はおそらく次の行です。

./qaswvd &

このコマンドはおそらくまだ実行されており、stdinとstdout&stderrが閉じるまでsshパイプを開いたままにします。

代わりにこれを使用してください:

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