<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <atom:link href="http://kitchingroup.cheme.cmu.edu/blog/feed/index.xml" rel="self" type="application/rss+xml" />
    <title>The Kitchin Research Group</title>
    <link>https://kitchingroup.cheme.cmu.edu/blog</link>
    <description>Chemical Engineering at Carnegie Mellon University</description>
    <pubDate>Sat, 01 Nov 2025 13:47:46 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    
    <item>
      <title>A helm interface to ps</title>
      <link>https://kitchingroup.cheme.cmu.edu/blog/2014/11/22/A-helm-interface-to-ps</link>
      <pubDate>Sat, 22 Nov 2014 12:57:42 EST</pubDate>
      <category><![CDATA[helm emacs]]></category>
      <guid isPermaLink="false">TOW03ZNV4izP7X9RRqp2zb-jvsI=</guid>
      <description>A helm interface to ps</description>
      <content:encoded><![CDATA[


&lt;p&gt;
Occassionally, I need to find the PID of a process to kill it or do something else. Usually I do the old-school unix thing  of piping the output of one command (ps) to another command (grep) to filter out interesting lines. Then, I can do something with that output.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-sh"&gt;ps aux | grep emacs
&lt;/pre&gt;
&lt;/div&gt;

&lt;pre class="example"&gt;
jkitchin         4781   3.1  0.8  2639316  70432 s002  S    12:45PM   0:06.68 /usr/local/Cellar/emacs/HEAD/Emacs.app/Contents/MacOS/Emacs
jkitchin         4777   0.0  0.0  2433364    932 s002  S    12:45PM   0:00.00 /bin/bash /usr/local/bin/emacs
jkitchin         4874   0.0  0.0  2432784    604   ??  S    12:46PM   0:00.00 grep emacs
&lt;/pre&gt;

&lt;p&gt;
Today, I will explore using helm in emacs to do something like that. The idea is to create a helm command that uses the output of ps as candidates, and then you select the process you want through the helm interface, and then select an action.
&lt;/p&gt;

&lt;p&gt;
It is easy enough to get the output of the ps command in emacs like this. Here, we just get the first three results, and specify the output we want.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((results (split-string
                (shell-command-to-string
                 &lt;span style="color: #228b22;"&gt;"ps x -o ruser,pid,command"&lt;/span&gt;) &lt;span style="color: #228b22;"&gt;"\n"&lt;/span&gt;)))
  (loop for i from 1 to 3
        collect (elt results i)))
&lt;/pre&gt;
&lt;/div&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #228b22;"&gt;"jkitchin   139 /sbin/launchd"&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"jkitchin   151 /usr/libexec/UserEventAgent (Aqua)"&lt;/span&gt; &lt;span style="color: #228b22;"&gt;"jkitchin   152 /usr/sbin/distnoted agent"&lt;/span&gt;)
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
These will be the candidates for the helm command. We will create a few actions. One will provide details about the pid, and one could in principle kill the pid or send some signal to it. We will just have these actions create message boxes for us to see helm in action. We will make the kill function interactive, so it allows an arbitrary signal to be sent. The other actions are placeholders for future actions, and so we can show off some shortcuts in helm later.
&lt;/p&gt;

&lt;p&gt;
For the candidates, we will construct a list of cons cells where the car is a line from ps, and that is what will show in the helm selection interface, and the cdr will be the pid which we get by parsing the line to get the second element. When you select an entry in helm, the cdr of that entry (if it exists) is passed to the action function selected.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-candidates&lt;/span&gt; ()
  &lt;span style="color: #228b22;"&gt;"return a list of cons cells (line . pid) for the output of ps"&lt;/span&gt;
  (loop for line in
        ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;skip the first line which is a header&lt;/span&gt;
        (cdr (split-string
              (shell-command-to-string
               &lt;span style="color: #228b22;"&gt;"ps ax -o ruser,pid,command"&lt;/span&gt;) &lt;span style="color: #228b22;"&gt;"\n"&lt;/span&gt;))
        collect
        (cons
         line
         (elt (split-string line) 1))))

(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-details&lt;/span&gt; (pid)
  &lt;span style="color: #228b22;"&gt;"give details of PID."&lt;/span&gt;
  (message-box &lt;span style="color: #228b22;"&gt;"%s"&lt;/span&gt; (shell-command-to-string (format &lt;span style="color: #228b22;"&gt;"ps ux %s"&lt;/span&gt; pid))))

(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-kill&lt;/span&gt; (pid)
  &lt;span style="color: #228b22;"&gt;"Message box instead of killing PID."&lt;/span&gt;
  (&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((SIG (read-string &lt;span style="color: #228b22;"&gt;"Kill with signal: "&lt;/span&gt;)))
    (message-box &lt;span style="color: #228b22;"&gt;"Killing pid %s with signal %s"&lt;/span&gt; pid SIG)))

(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-hello&lt;/span&gt; (pid)
  (message-box &lt;span style="color: #228b22;"&gt;"Silly 3rd action for %s"&lt;/span&gt; pid))

(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-bye&lt;/span&gt; (pid)
  (message-box &lt;span style="color: #228b22;"&gt;"Silly 4th action for %s"&lt;/span&gt; pid))

(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;ps-byebye&lt;/span&gt; (pid)
  (message-box &lt;span style="color: #228b22;"&gt;"Silly 5th action for %s"&lt;/span&gt; pid))

;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;the source variable for helm&lt;/span&gt;
(setq helm-source-ps '((name . &lt;span style="color: #228b22;"&gt;"ps output"&lt;/span&gt;)
                       ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;these are the entries you can select&lt;/span&gt;
                       (candidates . ps-candidates)
                       ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;these are the actions available for the&lt;/span&gt;
                       ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;selected entry. each function gets the cdr&lt;/span&gt;
                       ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;of the entry selected.&lt;/span&gt;
                       (action . ((&lt;span style="color: #228b22;"&gt;"details"&lt;/span&gt; . ps-details)
                                  (&lt;span style="color: #228b22;"&gt;"kill"&lt;/span&gt; . ps-kill)
                                  (&lt;span style="color: #228b22;"&gt;"hello"&lt;/span&gt; . ps-hello)
                                  (&lt;span style="color: #228b22;"&gt;"bye"&lt;/span&gt; . ps-bye)
                                  (&lt;span style="color: #228b22;"&gt;"byb-bye"&lt;/span&gt; . ps-byebye)))))

;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;now we run the helm command&lt;/span&gt;
(helm &lt;span style="color: #cd0000;"&gt;:sources&lt;/span&gt; '(helm-source-ps))
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;
You can navigate the helm interface with the arrows, or C-n (next/down) C-p (previous/up), or by typing in the pattern you want to match. There are only two actions here. The first one is the default action, which you can run by pressing tab or enter. The subtle difference between them is that tab leaves the helm window open, while enter runs the default action and closes the helm window. You can get it back with C-c h r (or M-x helm-resume). 
&lt;/p&gt;

&lt;p&gt;
To get the kill function, you can press C-z to get the action menu, and then press enter. Helm provides a shortcut for this. C-e selects the second action, so when you remember what the second action is and you want it, you can skip the C-z activity. You can access the third action with C-j. There is a command like helm-select-4th-action, but it is not bound to a key, so we have to make one like this.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(define-key helm-map (kbd &lt;span style="color: #228b22;"&gt;"C-k"&lt;/span&gt;) 'helm-select-4th-action)
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
You can also define a 5th action like this. It does not seem possible to define an arbitrary nth action, because you cannot get an input for n while helm uses the minibuffer. 
&lt;/p&gt;

&lt;div class="org-src-container"&gt;

&lt;pre class="src src-emacs-lisp"&gt;(&lt;span style="color: #8b0000;"&gt;defun&lt;/span&gt; &lt;span style="color: #8b2323;"&gt;5th-action&lt;/span&gt; ()
 (interactive)
 (&lt;span style="color: #8b0000;"&gt;let&lt;/span&gt; ((n 5))
   ;; &lt;span style="color: #ff0000; font-weight: bold;"&gt;actions start at 0, so the 5th action is actually indexed at 4&lt;/span&gt;
   (helm-select-nth-action (- n 1))))

(define-key helm-map (kbd &lt;span style="color: #228b22;"&gt;"C-l"&lt;/span&gt;) '5th-action)
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
That is the proof of concept in using a helm interface to interact with unix commands. There are other actions you might choose, like renice, or maybe it is possible to suspend a job by pid. The real application for this I had in mind was interaction with the Torque queue system, where you might want to modify, kill jobs in the queue system this way. I could also see applications in user management, where you have some well defined functions to run, e.g. checking quotas, changing passwords, etc&amp;#x2026; Clearly the utility of this approach rests heavily on there being a set of actions you do regularly enough to justify coding them into functions, and often enough you would remember to use your helm command! It is an interesting approach as an alternative to writing shell scripts to do this though.
&lt;/p&gt;

&lt;p&gt;
This post might make more sense if you watch this video of the helm interface in action: &lt;a href="http://www.youtube.com/watch?v=3FImB6OwHI0"&gt;http://www.youtube.com/watch?v=3FImB6OwHI0&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Copyright (C) 2014 by John Kitchin. See the &lt;a href="/copying.html"&gt;License&lt;/a&gt; for information about copying.&lt;p&gt;&lt;p&gt;&lt;a href="/org/2014/11/22/A-helm-interface-to-ps.org"&gt;org-mode source&lt;/a&gt;&lt;p&gt;&lt;p&gt;Org-mode version = 8.2.7c&lt;/p&gt;]]></content:encoded>
    </item>
  </channel>
</rss>
