ssh和shell通过ssh:如何退出?


22

我正在通过SSH这样启动远程脚本:

ssh user@ipaddress '~/my_script.sh'

一切都很好,但是一旦脚本完成,连接就不会关闭。我必须按CTRL-C断开当前连接。

我已经尝试过“〜/ my_script.sh”中的“退出”命令,它没有用。我已经尝试在“〜/ 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启动它时,它会运行,最后,我读到“全部完成”。所以这意味着到达了最后两行

任何想法我该怎么做才能自动关闭并公关


1
脚本中有什么?
伊格纳西奥·巴斯克斯

@Olivier:您转发任何端口(包括代理和X)吗?当命令终止并且所有TCP连接都已关闭时,ssh连接将关闭。
吉尔(Gilles)'所以

@Gilles:不,我只是做一个shell连接来运行一个脚本,没有任何转发。
奥利维尔·庞斯

1
@Olivier:如果您有一个~/.ssh/config,请尝试不使用它,然后将选项-a -x(和no -o)传递ssh给,以确保没有转发正在进行。如果仍然不起作用,请显示脚本的内容。
吉尔(Gilles)“所以

@Olivier:脚本是否启动可能正在等待的任何后台作业?不幸的是,在ssh脚本中,作业似乎未返回任何内容。示例:ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'将列出文件,显示完成并等待10秒钟后返回。
asoundmove 2010年

Answers:


19

Shell脚本中的退出不起作用,因为它是从脚本而不是Shell中退出。要在脚本完成后退出外壳,请执行以下操作:

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

这将运行脚本,然后从外壳退出。


3
它应该正在退出。脚本外壳。
暂停,直到另行通知。

@丹尼斯:这对他不起作用,所以可能可以。
Wuffers

2
@先生。Man:您的命令与原始命令等效,不同之处在于它强制外壳存在于其中sshd,并且外壳运行myscript.sh。在exit当脚本退出,这不利于你写的动作。解决方案唯一可行的方法是,如果脚本的父级是脚本,而脚本sshd的父级是shell,则该脚本执行奇怪的操作,而脚本的父级是shell,则不执行该操作。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

它有什么帮助?退出将关闭外壳并结束连接,对吗?这不是发布者想要做的吗?
Wuffers

3
@MrMan:~/my_script.sh && exit退出后立即~/my_script.sh退出。如果shell脚本没有退出,那么您的命令将永远无法达到目标exit。所以这没用。
吉尔(Gilles)“所以

12

如果有其他进程仍在使用ssh启动的进程(在此为shell)退出,则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或我都不起作用(不知道为什么接受它),我仍然想为未来的googler发布自己的解决方案。很简单:-fssh命令中添加一个选项:

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

编辑

-f选项的作用是放在ssh后台,因此,如果不添加任何其他选项,则即使看上去断开了连接,连接也可能仍然有效。如果有兴趣,可以参考本网站另一篇文章中给出的答案。


注意:如果原始脚本具有用于用户输入的提示,则此(-f)将不起作用。
madD7

3

像Ignacio一样,我很好奇您脚本中的内容。

也许您可以尝试将脚本简化为产生错误条件的最小示例。

或者从一个空脚本开始,一次添加一个命令,直到看到问题,然后您将知道是什么命令导致脚本被锁定。

如果空脚本导致您出现问题,则可能需要调查ssh配置,例如,.bash_logout或在退出时调用了某些类似内容可能会导致问题?


感谢您的建议,我现在在问题中添加了脚本示例。
奥利维尔·庞斯

@Olivier:您只添加了脚本中不相关的部分。发布一个脚本(必要时附有用法说明),以使读者重现您的问题。尽可能简化脚本,但不要进一步。
吉尔(Gilles)'所以

@吉尔斯谢谢你。我已经修改了问题,并添加了整个脚本。希望这可以帮助。看来问题可能出在我正在启动一个后台进程(“ ./qaswvd&”行)。这可能是问题的根源吗?
奥利维尔·庞斯

1
@Olivier:是的,您的主进程将在退出之前等待后台进程停止。如果要在退出后保持某些状态,请尝试使用nohup。虽然不确定它是否可以与ssh一起使用,但是尝试一下它不会有任何伤害。
asoundmove 2011年

2

您可能在脚本中使用作业。如果是这样的话,shell只会等待您的作业完成,并且不想分离自己。

我不会转发,只会转发给您http://en.wikipedia.org/wiki/Nohup#Existing_jobs


我已经修改了问题,并添加了整个脚本。希望这可以帮助。看来问题可能出在我正在启动一个后台进程(“ ./qaswvd&”行)。如果您是对的,这可能是问题的根源吗?
奥利维尔·庞斯

后台进程是问题所在,但nohup不是直接问题,因为服务器端没有终端:我认为罪魁祸首是打开文件描述符。
吉尔(Gilles)'所以

是的,我认为这是问题所在,您可以尝试发表评论,也可以通过上面的链接应用该黑客
Oleksiy Khilkevich 2011年


0

问题可能出在下面。

./qaswvd &

该命令可能仍在运行,并且将使ssh管道保持打开状态,直到关闭stdin和stdout&stderr。

使用此代替:

./qaswvd </dev/null >/dev/null 2>&1 &
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.