26

I have a problem regarding how to kill a process in Cygwin on Windows. I am completely new to Cygwin. But I have a task that I simply cant kill. I have tried issuing the following commands:

kill 4568
kill -9 4568
/bin/kill -f 4568

I have issued the commands in a separate Cygwin terminal since I cannot Ctrl+C it in the Cygwin terminal where the process run. I have searched all over the internet without success.

Zombo
  • 1
  • 24
  • 120
  • 163
user1093774
  • 369
  • 1
  • 3
  • 3

9 Answers9

30
ps -W | awk '/calc.exe/,NF=1' | xargs kill -f

Or

ps -W | awk '$0~v,NF=1' v=calc.exe | xargs kill -f

Or

powershell kill -n calc
Zombo
  • 1
  • 24
  • 120
  • 163
  • 1
    You may want to use `ps -W | awk 'BEGIN{ IGNORECASE=1;} /calc.exe/,NF=1' | xargs kill -f` because Windows is case-insensitive – tricasse Nov 07 '17 at 13:46
  • Make sure you use `/bin/kill`, the bash builtin `kill` doesn't have the `-f` switch. Using /bin/kill seems to work on git-bash, msys2 and cygwin. – cdleonard Mar 30 '23 at 06:54
11

You may try:

taskkill /pid 4568
aggu
  • 182
  • 4
8

If you want a BASH only solution, try this: (it works for me)

    KILLPS="<My Process Name>"
    WINPS=`ps -W | grep -i $KILLPS`         # Make case-insensitive.
    PID=`echo $WINPS | cut -d' ' -f1` 
    /bin/kill -f "$PID"

NOTE: use /bin/kill, the embedded shell kill will not kill PIDs for general windows proccesses.

dpminusa
  • 201
  • 2
  • 4
  • 2
    Your note about /bin/kill vs shell kill was very useful. Thanks – Phil May 09 '17 at 21:08
  • 1
    Like @Phil I also found the distinction between `kill` and `/bin/kill` to be unexpected, informative and ultimately very useful in stopping troublesome processes. Thanks! – AJM Jan 16 '23 at 13:44
2

Two things to think about here:

  1. Get the correct PID, which is the WINPID.
  2. Use the right tool.

To get the correct WINPID to kill, use cat /proc/<PID>/winpid. I.e. run this:

ZID=$$; WINPID=$(cat /proc/${ZID}/winpid); echo "Kill WINPID: ${WINPID}"; ps; sleep 10 &
 

and immediately after do another ps.

The right tool to use is Sysinternals' PsKill64.exe -t <winpid> which also kills all descendants of the script process, which kill doesn't.

AJM
  • 222
  • 1
  • 11
not2qubit
  • 1,993
  • 4
  • 28
  • 35
  • 1
    You got a vote for `cat /proc/${ZID}/winpid`, very good to know. And faster than solution with `ps -aW | grep ...`, at least on my cygwin under Win 7 x64. But for PsKill64 I think you need `-t` to kill sub processes, and `taskkill` can also kill subprocesses. – 244an Dec 19 '17 at 21:40
  • Yes, you also need the `-t` to kill descendants. Corrected answer. – not2qubit Dec 20 '17 at 14:47
  • I like this because you can access the command-line, but unfortunately it doesn't find all processes like children spawned by commands. – Wheezil Aug 31 '21 at 20:44
2

(From my answer to a similar question on SO):

Different Windows programs will handle the signals that kill sends differently; they've never been designed to deal with them in the same way that Linux/Cygwin programs are.

The only reliable method for killing a Windows program is to use a Windows specific tool, such as Task Manager or Process Explorer.

That said, if you've not already, you may have luck with running your Cygwin terminal in administrator mode (right click on your shortcut and select "Run as administrator").

me_and
  • 2,247
  • 4
  • 19
  • 26
1

If you have a Windows program that is a subprocess under a cygwin bash process you can use taskkill /F /PID [the cygwin process id] /T to kill the process tree, no need to get the Window PID from ps with awk etc.
This is tested under Win7 x64.

# Simple example in cygwin:
> notepad.exe &
> pid=$!
...
> taskkill /F /PID $pid /T

Of course you can use the Window PID also.

244an
  • 111
  • 4
0

In Git Bash I use:

targetProcess='chromedriver.exe';
ps -W | grep -i ${targetProcess} | awk '{print $1}' | while read pid; do taskkill //PID ${pid}; done;

I have not tried it in Cygwin, but I suppose it will work there too.

0

Extending other answers, I found this to be a useful pattern. Note cutting the WINPID column:

for pid in `ps -W | grep 'processname' | tr -s ' ' | cut -d ' ' -f 5`
do
    echo killing $pid
    taskkill /F /pid $pid
done
Wheezil
  • 101
  • 2
0

I had a more challenging situation than most of these answers considered: killing the Windows process by executable name (node.exe) was too broad so I had to find the WINPID by looking at the command line arguments. And unfortunately, the cygwin ps command doesn't show commandline arguments.

Another challenge was, although my process was spawned in cygwin, it created child processes that couldn't be seen in any ps except ps -W.

As an aside, you can find command line arguments for your visible cygwin processes by running this: grep -a "" /proc/*/cmdline | xargs -0 But that didn't help me in this situation because the process I wanted to kill wasn't visible by cygwin and therefore wasn't in that output.

Fortunately, Windows (10, at least) comes with a command line tool you can run in cygwin to get command name and argument information. Here's how: wmic process get ProcessID, Commandline /format:csv. The output looks something like this:

DESKTOP-ABC,E:\Windows\system32\lxss\wslhost.exe {xxx} x y z {xxx},180
DESKTOP-ABC,\??\E:\Windows\system32\conhost.exe 0x6,2295
DESKTOP-ABC,E:\Windows\system32\svchost.exe -k ClipboardSvcGroup -p -s abcdef,430

The last column of that output is the Windows process ID.

Other answers here claim you can /bin/kill -f $WINPID those, but when I tried, it reported this error: kill: illegal pid: $WINPID. I suspect this has something to do with cygwin not running in administrator mode?

Additional answers say to taskkill /pid $WINPID but when I tried, it reported this error: ERROR: Invalid query.

But this line from @244an's answer worked for me: taskkill /F /PID $WINPID /T.

I decided to post this as a separate answer because, in my humble opinion, the information that led up to this line is just as valuable as the answer itself: it provides a variety of ways to get the Windows PID from cygwin even if the process isn't visible in cygwin.

I also want to say it was challenging to figure out how to pass a variable into taskkill due to line return issues. wmic, being a Windows command, returns Windows line endings (\r\n). Cygwin assumes its commands are going to receive you unix endings (\n). Due to this, taskkill output some very unhelpful error messages. The tr in this pipeline is how I resolved that:

wmic process get ProcessID, Commandline /format:csv | tr -d '\r' | grep -- 'search term' | awk -F, '{ system("taskkill /F /PID " $NF " /T") }'

It removes every '\r' from the output. This awk says, the field separator for every column is a comma. The awk script says, "for every line grep finds, run taskkill on the last column (i.e., $NF) of the csv output.

Daniel Kaplan
  • 579
  • 8
  • 23