0

I take notes in class on my computer and share these notes via a public folder on dropbox. When I take notes in class, I create a lot of unnecessary files (I take notes in LaTeX) before I generate a PDF. I don't want to clutter my dropbox space with the unnecessary files, and would rather post only the PDFs to dropbox.

In order to facilitate all of this, I set up a cronjob that runs a python script (below) after every class (weekly). Sometimes, I stay back for a few minutes while I fix something in my notes before I export a PDF, so the python script has a bunch of sleeps in it, waiting for the PDF to be generated. I accidentally manually ran that script today, and need help stopping it.

import os
import subprocess

from sys import exit as crash
from datetime import date as dt
from time import sleep

def getToday():
 answer = dt.strftime(dt.today(), "%b") + str(int(dt.strftime(dt.today(), "%d")))
 return answer

def zipNotes(date):
 today = getToday()
 while 1:
  if today not in os.listdir('.'):
   with open("FuzzyLog", 'a') as logfile:
    logfile.write("Sleeping\n")
   sleep(60*5) # sleep 5 minutes
   continue
  if "Notes.pdf" not in os.listdir(today):
   with open("FuzzyLog", 'a') as logfile:
    logfile.write("pdf not exported. Sleeping\n")
   sleep(60*5) # sleep 5 minutes
   continue

  subprocess.call("""zip Notes.zip */Notes.pdf""", shell=True)
  crash(0)

zipNotes(getToday())

Since the script doesn't find any files made today (I could easily just create a dummy file, but that's not a "proper" solution), it loops through the sleep condition infinitely. Since the looping conditions are quite simple, I can't count on the process to be active for very long to "catch it in the act" to get its PID to kill it.

ps aux | grep python doesn't show me which PID is running the python script I want to kill, nor does ps -ax | grep python or ps -e | grep python.

Does anyone have any idea how I can track a python script while it's sleeping?
I'm on Mac OSX 10.7.5 (Lion), if that matters

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • If you're going to update the script to make it easier to find and kill, why not update it to make it possible to shut down cleanly instead? – abarnert Oct 03 '13 at 23:37
  • @abarnert: I /could/ update the script (how?), but for now, I'm stuck with a script that's already running and needs to be killed. How may I go about finding and killing this script? – inspectorG4dget Oct 03 '13 at 23:40
  • Well, for this one-time case, just create the dummy file that it's waiting for. Then look at how to make that unnecessary in the future. – abarnert Oct 03 '13 at 23:44
  • I don't understand why ps -e wouldn't display the pid of the process. The fact that it's sleeping shouldn't make any difference. – Ioan Alexandru Cucu Oct 03 '13 at 23:53
  • @IoanAlexandruCucu: I don't understand it either. – inspectorG4dget Oct 03 '13 at 23:54
  • So what makes you think the script is still running? Isn't there a chance that it might have crashed? – Ioan Alexandru Cucu Oct 03 '13 at 23:59
  • @IoanAlexandruCucu: check out the code, it logs to a file – inspectorG4dget Oct 03 '13 at 23:59
  • Are the logs still being written to? If yes, you could probably do a lsof on the log files and see what process continues to write them. But I honestly doubt your script is still running... – Ioan Alexandru Cucu Oct 04 '13 at 00:00
  • @IoanAlexandruCucu: I just found it. The script /is/ still running. The reason it didn't show up on `ps aux | grep python` is because osx likes things to be capitalized; my process showed up when I did `ps aux | grep Python` (note the capitalization in `Python`) – inspectorG4dget Oct 04 '13 at 00:02
  • Well, doing a 'lsof FuzzyLog' would have helped you discover this faster. Anyways, funny story :) – Ioan Alexandru Cucu Oct 04 '13 at 00:06
  • Thanks @IoanAlexandruCucu for reminding me about `lsof`. I should write it down for next time – inspectorG4dget Oct 04 '13 at 00:08

1 Answers1

1

The traditional way Unix daemons handle this problem is with "pid files".

When your program starts up (or when your launcher starts your program up), it creates a file in a well-known location (/var/run/<PROGRAM NAME>.pid for system daemons; per-user daemons don't have a universal equivalent), writes the PID into that file (as in the ASCII string 12345\n for PID 12345), and deletes it when it exits. So, you can just kill $(cat /var/run/myprogram.pid).

However, it doesn't seem like you need this here. You could easily design the program to be cleanly shutdown, instead of designing it to be killable.

Or, even easier, remove the sleep; instead of having cron run your script it every hour and having the script sleep for a minute at a time until the PDF file is created, just have LaunchServices run the script when the PDF is created.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • I just looked it up and get how LauchServices can be used (in theory). But seeing as I've never come close to working with it before, is there a simpler solution (I'm working on creating the file for this one time)? Alternatively, would you be able to point me in the right direction, so I could start my first experiment with LaunchServices? – inspectorG4dget Oct 03 '13 at 23:52
  • @inspectorG4dget: [Creating Launch Daemons and Agents](https://developer.apple.com/library/Mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html) is the best place I know of to start. It has some sample launchd plist files (like cron schedules, but more flexible and a lot more verbose) for different use cases, like running your program every time a file gets added to a specific directory. – abarnert Oct 03 '13 at 23:57
  • @inspectorG4dget: Also, if the reference docs linked from that guide are still incomplete (I haven't really looked since 10.4 or 10.5 or so), `man launchd.plist` should have all the details. – abarnert Oct 03 '13 at 23:57
  • Thank you. I am looking this up right now and will let you know if I run into more trouble – inspectorG4dget Oct 03 '13 at 23:58
  • 1
    @inspectorG4dget: I'm sure you'll enjoy writing simple shell command lines in XML as much as everyone else does. :) But the ability to run stuff of all kinds of fancy triggers instead of just a timer means it's often worth it. – abarnert Oct 03 '13 at 23:59