web-dev-qa-db-ja.com

sshとsshを介したシェル:終了するには?

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

ssh user@ipaddress '~/my_script.sh'

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

「〜/ my_script.sh」で「exit」コマンドを試しましたが、役に立たないのです。 '〜/ my_script.sh'の "logout"コマンドを試したところ、次のメッセージが表示されました。

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を介して起動すると、実行され、最後に"All done。"と表示されるので、これは最後の2行に到達することを意味します

どのように私が自動的に終了してPRすることができるか

24
Olivier Pons

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

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

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

20
Wuffers

まだ使用している他のプロセスがある場合、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のドキュメントを確認してください。 「デーモン化」ユーティリティを調査することもできます。

私は同じ状況の解決策をグーグル検索したときにこの投稿を見ました。 @Oliverの問題を解決するのは少し遅いですが、受け入れられた回答がOPにも私にも明らかに機能しなかった(なぜ受け入れられたのかわからない)ため、今後のGoogle社員向けに独自の解決策を投稿します。それは簡単です:sshコマンドに-fオプションを追加します:

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

編集

-fオプションの効果は、バックグラウンドでsshを配置することです。そのため、追加のオプションを追加しないと、接続が壊れているように見えても、接続がまだ有効である可能性があります。興味があれば、このサイトの別の post で与えられた答えを参照することができます。

5
Leo Fang

イグナシオと同様に、スクリプトの内容を知りたいです。

おそらく、スクリプトをエラー状態を生成する可能な限り小さい例に減らしてみることもできます。

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

空のスクリプトが問題を引き起こす場合、たとえば.bash_logoutなどのssh構成を調査する必要があるかもしれません。

3
asoundmove

スクリプトでジョブを使用している可能性があります。その場合、シェルはジョブが完了するまで待機するだけで、自分自身を切り離したくありません。

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

2

スクリプト内から親プロセスを強制終了する必要があります。

kill -SIGHUP $PPID

1

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

./qaswvd &

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

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

./qaswvd </dev/null >/dev/null 2>&1 &
0
edirks