如何关闭除当前以外的其他shell?

时间:2015-02-18 11:48:27

标签: regex bash shell unix tty

我需要一个简单的脚本来关闭除我当前登录的其他shell /会话之外的其他shell /会话。我坚持这一行:

ps -o pid,tty,comm | grep sh$

这会导致选择当前的shell。

例如:

 1346 136,0  sh
 1355 136,1  sh

我可以使用tty命令来了解我当前的shell(pts)。然后,我想我需要一个循环。

解决:

ps -o pid,tty,comm | grep sh$ | grep -v $$ | awk '{print $1}' | xargs kill -9

7 个答案:

答案 0 :(得分:1)

这实际上并不像最初看起来那么容易。主要挑战是ps实用程序在不同平台之间相当不兼容,这会产生一个非常大的风险,即您对ps的假设在您可能使用的系统上始终是正确的。脚本。而且由于任务是一个相当...... 危险的任务,你需要在这里小心。举个例子,我当前系统上的ps(Cygwin)没有-o选项,而你的选项似乎有pidCol=$(ps| head -1| awk '{ for (i = 1; i <= NF; ++i) if ($i == "PID") { print(i); exit; }; };'); if [[ -n "$pidCol" ]]; then ps| tail -n+2| grep sh$| cut -c2-| awk "{ print(\$$pidCol); };"| grep -v "^$$\$"| xargs kill -9; fi;

无论如何,这是我的解决方案:

ps

首先获取ps输出中包含进程PID的列号。我尝试通过解析$pidCol标题行使其尽可能健壮。因此,如果PID列位置在不同系统之间变化,我们仍应正确地为当前系统获取它。

然后,我已经在kill管道周围应用了一个警卫,以确保它只在我们从parse命令成功获得sh时才会运行。

然后,在实际的kill管道中,我删除了所有ps进程的头,grep,切断了第一个字符(因为某些系统上的awk在开头打印了一个小字符指示符某些(但不是全部)行没有在标题行中获得相应的列名称,然后使用xargs kill -9只打印PID列值。最后,我将查看当前进程的PID并通过{{1}}运行剩余的PID。

答案 1 :(得分:1)

您可以在此$$管道ps中使用awk {/ 1}}:

ps -o pid,tty,comm | awk -v curr=$$ '$3 ~ /sh/ && $1 != curr'

变量$$表示当前shell的PID。

答案 2 :(得分:0)

运行以下命令以获取正在运行的会话的PID(进程ID):

ps -ft

使用这些PID强制终止进程:

kill -TERM <PID1> <PID2> <PID3>

BASH中使用循环来完成所有操作,不包括当前会话

答案 3 :(得分:0)

您可以使用tty和&#34;清洁&#34;来获取当前的shell它可以在第二次斜杠之后得到数据:

current=$(tty | cut -d/ -f3-)

然后,打印ps -o pid,tty,comm中的所有结果,第二列与当前列不匹配......并将标题删除:

ps -o pid,tty,comm | awk -v current="$current" 'NR>1 && $2!=current {print $1}'

然后,您可以遍历此结果并kill给定的PID。

答案 4 :(得分:0)

试试这个。

pts=$( tty | sed 's/\/dev\(*\)/\1/' ) 
current=$( ps -C sh  | grep $pts | ps -o pid= | head -n 1 )
total=$(ps -C sh -o pid= )
for i in $total ; do                         
    if [[ $i -ne $current ]] ; then
            kill -9 $i
    fi
done

答案 5 :(得分:0)

pgrep -u $USER | grep -v "`pgrep -s 0`" | xargs kill

这将获取当前用户的所有PID列表,并删除当前会话的PID。然后通过xargs将其全部提供给kill以终止。

答案 6 :(得分:0)

我用这个:

#!/bin/bash
current=$(tty | cut -d/ -f3-)
all=$(ps -A -o tty | grep pts/ | grep -v $current)
for i in $all ; do
    pkill -9 -t $i
done