Fork 'post-process on the command line'

Hi All,
I run my Scrivener project through a post-processing script. For large jobs, it would be convenient if I could fork this process, so that Scrivener returns while the process is still running. (Currently, the compile window will hang around until all processing is done). Is there a way to do this? Everything I’ve tried failed. This is probably by design, so that scrivener doesn’t create any evil zombie processes, but still… Ideas?

You could run it as two separate tasks:

  • Scrivener compiles, saves the output to a file, exits from the Compile command.

  • The post-processing script takes the output file as input. It’s fairly easy to automate this by having the script run whenever a new/changed file appears in a designated folder.

This is probably a more robust way to do it anyway, since you can insert whatever additional backup steps that you like in between, and can debug the script and the Compile settings separately.


Thanks, Katherine. That’s exactly what I have now – I have scrivener output a mmd file, a folder that is watched for changes in the mmd file. I was just wondering if instead of watching the folder, I can trigger the post processing from Scrivener itself (w/ the caveats above, a fork and so on). But, for the record, you solution works perfectly well.

I haven’t tried it myself, but have you tried using the Processing compile format pane to call upon a wrapper script that itself does the fork and then exits cleanly? That might work.

The trick here, in case you’ve never run across this sort of situation, is to use the “nohup” command to do the ahem forking. I’ve used “nohup > /logs/script.log &” in hundreds of scripts to allow the first script to launch another but not cause the called script to be killed by the system when the caller exits.

Thanks, Folks. Yeah, I’m a novice at this sort of thing, so sorry if I’m using wrong terminology.

@rdale: I did try the nohup option, and it doesn’t work: Scrivener still waits until all processing is done. The issue is not that I’d like a script to launch another but not cause the called script to be killed by the system when the caller exits. Rather, it is that I’d like the caller to exit before the called script completes.

@AmberV: I tried that too. Perhaps I’m not doing things properly, but thus far, Scrivener always waits until all called scripts are done. I’ll have a go at that approach again, but I’ve tried several permutation that didn’t succeed.

EDIT: tried again w/ a wrapper script. Indeed, makes no difference. I can run the script directly from the command line, and it returns before the processing is done, as intended. But when I call the same script from Scrivener, Scrivener waits until all processing is done.

It looks like there might be a way of doing this, but it would have to be specifically coded for, and probably provided as an option (one that disabled other options, like post-compile clean up) given how it would not be a desirable result for most uses.

I tested using another program that integrates with the shell (Keyboard Maestro) by creating a simple macro that first executes a script with a fork in it (just a simple Ruby one-liner that sleeps for five seconds and then uses the say command) using the ‘&’ convention, and then following that action, one that types text into the current editor. With default settings it took five seconds for the macro to finish and type in the test string. But I poked around and found an optional flag to execute the script asynchronously. I set that, and immediately upon execution the sample text was typed into the editor, and then five seconds later the Mac said “done” out loud. So again, in theory, possible—but it’s a specific NSTask flag I bet, that has to be set by the software running the command.

As Ioa pointed out, it may be more complicated than is shell scripting, but I thought I’d point out the & at the end of the line is supposed to send the process into the background, allowing the rest of the calling script to continue (or exit if it reaches the end) before the called script finishes. The nohup is just a command telling the OS not to “hang up” on the called script (don’t kill it, in other words) if the caller exits before it’s finished.

Sadly, if I understand Ioa’s last response, Scrivener may have to be programmed to allow this sort of thing.

Yup, thanks rdale.