我正在尝试使用以下命令在 Ubuntu 上重新启动 SSH:
sudo /etc/init.d/ssh restart
但这只是给了我:
不要通过 /etc/init.d 调用 init 脚本,而是使用 service(8) 实用程序,例如 service ssh restart
但是,运行结果为:
重新启动:未知实例:
跑步:
ps -A | grep ssh
给出 3 个实例。
问题
我如何知道哪个是我的实例,并终止其他实例?这样我就可以重新启动吗?
有人能帮我解决这个问题吗?
答案1
调用 init.d 脚本仍然应该重新启动该服务:
dermot@porkboy:~$ sudo /etc/init.d/ssh restart
[sudo] password for dermot:
Rather than invoking init scripts through /etc/init.d, use the service(8)
utility, e.g. service ssh restart
Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the stop(8) and then start(8) utilities,
e.g. stop ssh ; start ssh. The restart(8) utility is also available.
ssh stop/waiting
ssh start/running, process 4877
dermot@porkboy:~$
'service ssh restart' 在这里工作正常(11.04)。值得注意的是,重新启动 sshd不会终止现有的 SSH 会话。当您通过 SSH 登录到框时,sshd 会生成新进程来处理会话。重新启动 sshd 将终止主 sshd 守护进程(显然会重新启动它),但不会改变其他生成的 sshd 实例。您需要这种行为,因为当您在远程数据中心使用无头服务器时,它会让生活变得轻松很多!
现在,回答你的其余问题。不要运行“ps -A”,而是尝试以下操作:
dermot@porkboy:~$ ps -ef | grep ssh
root 2522 1 0 Aug29 ? 00:00:00 sshd: dermot [priv]
dermot 2615 2522 0 Aug29 ? 00:00:04 sshd: dermot@pts/0
root 4655 1 0 10:52 ? 00:00:00 sshd: dermot [priv]
dermot 4756 4655 0 10:52 ? 00:00:00 sshd: dermot@pts/1
root 4887 1 0 10:55 ? 00:00:00 /usr/sbin/sshd -D
这可能解释了您看到的三个 sshd 进程 - 一个用于主 sshd 守护进程,然后每个会话有两个(root 父进程,dermot 子进程)。我从两个位置通过 SSH 登录,因此我有五个进程。pts/X 位与会话所连接的虚拟终端相关,因此...
dermot@porkboy:~$ who
dermot pts/0 2011-08-29 21:32 (williams-mb.local)
dermot pts/1 2011-08-30 10:52 (192.168.253.109)
... 让我们知道哪个会话是哪个。因此,如果我想从 MacBook 中终止会话,我会使用“kill -9 2522”。
答案2
使用以下命令重启 SSH 守护进程
sudo /etc/init.d/ssh restart
或者
service ssh restart
监听守护进程将使用新的配置选项重新启动(我假设您重新启动它以使新配置生效)。所有已打开的会话仍使用旧配置运行。要了解哪个 ssh 会话是您的,请尝试执行:
ps -ef | egrep '(ssh|PID)'
您将获得一个/usr/sbin/sshdPPID 为 1,UID 为根。这是监听守护进程。所有其他sshd:用户@pts/0记录的是用户会话。根据用户名查找相应的会话,然后终止进程以终止此会话。
我建议在GNU 屏幕会话,所以如果你犯了一个错误,你将能够重新连接并重新附加此屏幕会议。
或者说我没有正确理解这个问题。
答案3
如果你想知道哪一个sshd
s 属于你,这真的很容易:
$ ps -aef --forest | egrep "(sshd|PID|David Newcomb is ace)"
UID PID PPID STIME TTY TIME CMD
root 1234 1 2018 ? 00:02:13 /usr/sbin/sshd
root 30546 1234 19:54 ? 00:00:00 \_ sshd: root@pts/0
root 32069 30548 20:17 pts/0 00:00:00 | \_ egrep (sshd|PID|David Newcomb is ace)
root 30692 1234 19:56 ? 00:00:00 \_ sshd: root@pts/1
root 31890 1234 20:16 ? 00:00:00 \_ sshd: root [priv]
sshd 32054 31890 20:16 ? 00:00:00 | \_ sshd: root [net]
root 31891 1234 20:17 ? 00:00:00 \_ sshd: [accepted]
sshd 32065 31891 20:17 ? 00:00:00 \_ sshd: [net]
你就是那个运行的人egrep
!
答案4
下面是我编写的一个脚本,它将终止除当前会话(运行脚本的会话)之外的所有 SSH 会话:
非常感谢大卫·纽科姆和帕特里克为创建此脚本提供帮助。
#!/bin/bash
# Many thanks to stackoverflow.com user "patrik" for the following
containsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
SKIP_PIDS=()
ALL_PIDS=()
SESSIONS=`sudo ps -aef --forest | egrep "(sshd|__MY_ID__)"`
# Get root PIDs and add them to the skip list
ROOT_PIDS_STR=$(echo "$SESSIONS" | grep 'root' | sed -E 's/[[:space:]]+/@@@/g' | tr "\n" ' ')
ROOT_PIDS=($ROOT_PIDS_STR)
# Collect root PIDs and add them to the skip list
for LINE in "${ROOT_PIDS[@]}"; do
LINE=$(echo "$LINE" | sed -E 's/@@@/ /g')
PID=$(echo "$LINE" | cut -d ' ' -f 2)
SKIP_PIDS+=($PID)
done
# Get my PID and add to the skip list
MY_PID=`echo "$SESSIONS" | grep -B 1 '__MY_ID__' | head -n 1 | sed -E 's/[[:space:]]+/ /g' | cut -d ' ' -f 2`
SKIP_PIDS+=($MY_PID)
# Get all PIDs, and only add those that aren't in the skip list
PIDS_STR=$(echo "$SESSIONS" | grep -v '__MY_ID__' | sed -E 's/[[:space:]]+/@@@/g' | tr "\n" ' ')
LINES=($PIDS_STR)
# Add all non-skip PIDs to the list of processes to kill
for LINE in "${LINES[@]}"; do
LINE=$(echo "$LINE" | sed -E 's/@@@/ /g')
PID=$(echo "$LINE" | cut -d ' ' -f 2)
containsElement "$PID" "${SKIP_PIDS[@]}"
if [ $? -ne 0 ]; then
ALL_PIDS+=($PID)
fi
done
# Kill all PIDs not in the skip list
for PID in "${ALL_PIDS[@]}"; do
sudo kill -15 "$PID"
done