Nq – A simple Unix job queue system
github.com
github.com
Overall, a clever trick I intend to steal.
NQDIR Directory where lock files/job output resides.
Each NQDIR can be considered a separate queue.
Whether or not the default should be $XDG_CACHE_HOME/nq/<something> is a different question. For my own use cases with nq I like the current directory being used, but it would obviously be just as easy for me to set `NQDIR=.`.> By default, job ids are per-directory, but you can set $NQDIR to put them elsewhere. Creating nq wrappers setting $NQDIR to provide different queues for different purposes is encouraged.
Can't claim any credit for the idea though, it was actually suggested in the documentation...
It might be possible on other unix systems too, but I never had to try it.
https://www.ibm.com/support/knowledgecenter/ssw_aix_72/print...
An example using ksh:
https://www.ibm.com/support/knowledgecenter/ssw_aix_72/files...
I recall consider doing it for the SunOS box we had, but lpd/lpr (what I think of as "the BSD print spooler") was sufficiently different that while it would have been possible, it wasn't worth the extra hassle to get one more machine to be able to render on.
I don't think we ever set it up to shuffle render spool jobs from one host to another, though. And, no, "doing raytracing" was not at ALL what the machines were supposed to do, they just weren't very loaded from their normal workloads, so some of the staff played around with it for fun.
When I think of it even lftp has queue and jobs commands. But "task spooler" is the generic tool you can use for more general use cases than file copying.
0. https://superuser.com/questions/220364/how-to-run-commands-a...
Wish it has chaining of commands - if xx fails then do yyy
Something like
parq add --task-name wget1 wget http://example.com/foo.json
parq add --task-name wget2 wget http://example.com/bar.json
parq add --dependencies wget1,wget2 jq -s '.[0] * .[1]' foo.json bar.json
parq run -n 2 # executes wget1 and wget2 in parallel using two workers, then merges them with jq $ make jq -j2 -f - <<EOF
file1:
wget file1
file2:
wget file2
jq: file1 file2
jq file1 file2
EOF
Could probably make some syntactic sugar for this.OTOH, if just working on one node, skip nq and use Snakemake as the scheduler as well.
https://gitlab.com/sdwolfz/cache_box_rb
I guess some slight tweaks for task persitance and a CLI wrapper for it could let you achieve this (although I don't leverage Ractors so no true parallelism yet).
Anyway, it still does not have an "official" release, nor a stable API, although the code works well and it's fully tested, as far a I can tell. I might consider providing such wrapper myself in the future as I can definitely see it's utility, but time is short nowadays.
Consider trying redo[0]. It's an idea of D. J. Bernstein (a.k.a. djb) what could already be a good advertising.
Your problem can be solved with make as it pointed by others but I see a wonderful example where redo's target files are pretty clear describing what redo can do.
redo's target files are usually SHELL-scripts but they can be whatever you want if it can be executed by a kernel. `redo-ifchange file1` is a command which waits until file1 have been rebuilt or, by other words, waits until a file1's target file have been executed if it requires.
There are 4 target files to show how to solve your problem --- downloading and merging two files:
all.do file is
DEPS="foo.json bar.json"
redo-ifchange $DEPS
jq -s '.[0] * .[1]' $DEPS
foo.json.do file is curl "http://example.com/foo.json" # redo guarantees that any errors won't update foo.json as it can happen in make world.
bar.json.do file is curl "http://example.com/bar.json"
After creating these files you could write `redo all` (or just `redo`) and it will create a graph of deps and will execute them in parallel --- foo.json and bar.json will be downloading at the same time.I'd recommend getting started with a Go version of redo --- goredo[1] by stargrave. There is also a link to documentations, FAQ and other implementations on the web-site.
There are a number of tools in this category, and like others have mentioned, my first try would be Make, if that is an option for you. However, I normally work on HPC clusters, so submitting jobs is incredibly common for me. To keep with that workflow without needing to install SLURM or SGE on my laptop (which I've done before!?!?), my entry into this mix is here: https://github.com/compgen-io/sbs. It is a single-file Python3 script.
My version is setup to only run across one node, but you can have as many worker threads as you need. For what you asked for, you'd run something like this:
$ sbs submit -- wget http://example.com/foo.json
1
$ sbs submit -- wget http://example.com/bar.json
2
$ sbs submit -afterok 1:2 -cmd jq -s '.[0] * .[1]' foo.json bar.json
$ sbs run -maxprocs 2
This isn't heavily tested code, but works for the use-case I had (having a single-file batch scheduler for when I'm not on an HPC cluster, and testing my pipeline definition language). Normally, it assumes the parameters (CPUs, Memory, etc) are present as comments in a submitted bash script (as is the norm in HPC-land). However, I also added an option to directly submit a command. stdout/stderr are all captured and stored.The job runner also has a daemon mode, so you can keep it running in the background if you'd like to have things running on demand.
Installation is as simple as copying the sbs script someplace in your $PATH (with Python3 installed). You should also set the ENV var $SBSHOME, if you'd like to have a common place for jobs.
The usage is very similar to many HPC schedulers...
sbs submit
sbs status
sbs run
sbs cancel
etc...I've used (and installed) PBS, SGE, and SLURM [1]. Most of the clusters I've used recently have all migrated to SLURM. Even though it's pretty feature packed, I've found it "easy enough" to install for a cluster.
What is the sales pitch for OAR? Any particularly compelling features?
OAR, according to knowledgeable people I've worked with, is robust and extensible.
$ cat Makefile
url_base := http://example.com
%.json:
wget $(url_base)/%.json
.PHONY: all
all: foo.json bar.json
jq -s '.[0] * .[1]' $^
$ make -j 2> cat - concatenate files and print on the standard output
> nohup - run a command immune to hangups, with output to a non-tty
> at — execute commands at a later time
Anyway, it's good to see new conceptual tools being developed for the Unix Toolbox, keep up!
> Build targets clean, depends, all, without occupying the terminal
This accommodates a workflow where one wouldn't prefer to just open up another terminal to do other stuff (maybe you're not in a graphical environment, maybe there's no tmux, etc.). With just the shell features, one could do `make ... && make ... && make ... &`, but that would cause bothersome output that would prevent you from effectively working in the same terminal. One could redirect the output of those commands, but then you lose it, or you have to think of where to collect it. This provides an alternative where you can background and still have convenient access to the output when you need it.
The other use is something like:
$ nq mpv $youtube_url
$ #work... work... work....
$ nq mpv $next_youtube_url
so that the next starts when the first finishes.
The scriptability of mpv is really nice if you're the sort of person who likes building your perfect environment, and also a huge pit of addictive time sinks. </warning>
make .. && make foobar && make ..
and you wanted to just run 'make foobar' again you'd search your history for the last foobar invocation, and be required to do some editing. With nq this wouldn't be necessary.
It's also not clear to me if nq has '&&' or ';' semantics in the event a command fails. I suspect it's ';'.
Clever and fun tool but unlikely I'll adopt it.
Some attempts:
* shell-controllable queue of commands * queue for running commands one after another
but I still think the README's is the best.
Obviously it's a queue and it's as simple as `nq cmd`. Also one can see the status with `fq`
It queues up Unix (shell) jobs. Do you understand what's meant by a shell "job"? Like "cmd &"?
Typing "cmd1 &", "cmd2 &", etc, runs jobs in parallel. "nq cmd1", "nq cmd2", runs them serially, in a queue.
cmd && cmd2 &
edit: From reading other comments I guess the difference is not mainly that it keeps running if the shell dies but that it allows you to easily append new stuff to the end of the queue
There are a lot of examples and a FAQ section + a Wiki, if you're interested in more information why one might need such a tool.
$ some_command &
$ wait; another_command &
$ wait; yet_another_command &
$ ...
Some other lightweight command queue strategies:* Use a background screen or byobu session. Advantage is that you can attach to it and monitor running tasks.
* bq is a bash script that lets you run a worker process and submit commands to be run in sequence. Nice because it's just a shell script.
Is that a typo? Why would you need {ugo}+x to tail a file?
[edit -- sorry, it's not tailing; somehow I read `tail -F` instead of `ls -F`.]
> Due to the initial exec line in the log files, you can resubmit a job by executing it as a shell command file, i.e. running sh $jobid.
(and many shells have a legacy behavior of running a file as a script if it doesn't start with a #! line.)
execlp and execvp are actually guaranteed to do this in POSIX-2017, although shells might also do this themselves if they resolve $PATH by themselves.
my `man ls` has:
-F, --classify
append indicator (one of */=>@|) to entrieshttps://www.gnu.org/software/coreutils/manual/html_node/Gene...
⌘ https://man.archlinux.org/man/run-parts.8
Many Linux distros use this command in the global crontab to serialise daily, weekly, monthly and annual batch jobs.
Thanks for the suggestion!
Even the examples provided describe what can already be done by appending a simple & to a command:
% mkdir -p /tmp/downloads
% alias qget='NQDIR=/tmp/downloads nq wget'
% alias qwait='NQDIR=/tmp/downloads fq -q'
window1% qget http://mymirror/big1.iso
window2% qget http://mymirror/big2.iso
...
what about? wget http://mymirror/big1.iso &
wget http://mymirror/big2.iso &
It all just seems to be trying very hard to be something it's not, but I can't put my finger on it. ( wget http://mymirror/big1.iso; wget http://mymirror/big2.iso ) &Run the queue:
mkfifo q
( while True; do sh q; done ) &
Schedule jobs: echo wget http://mymirror/big1.iso > q
echo wget http://mymirror/big1.iso > q
This has the added benefit of supporting multiple queues.roff is a terrible way to write a document. Its format is ancient and not well documented. Its behavior is not consistent across different implementations. Worst of all, no proper i18n support.
There's a tool like roff2html, but again it's pretty sketchy in terms of reliability and i18n support. I wrote my own converter when I was translating OpenBSD manpages [1], but I hope more people recognize this issue. [1] https://github.com/euske/openssh-jman/blob/master/roff2html....
curl cht.sh/grep
⌘ https://github.com/kseistrup/timestamp/tree/master/src
The scdocs havde the extension .md because Microsoft Github thinks .sc is SuperCollider files, whatever that is. The .1 files are “compiled” from the .1.md sources.
This seems a bit over the top, what is the advantage of giving up the rights to your work so slavishly?
It happens to be a convenient way to ensure that things are mostly used in a personal context. Most lawyercats will steer clear of software under these terms, and use under such terms is typically disallowed in any megacorp.
Is it because it's unclear whether such a statement would really waive all copyright?
Edit: that seems to be it; here are Google's views on the matter: https://opensource.google/docs/thirdparty/licenses/#unencumb...
I wonder whether there's a better way to express it. E.g. "if you see this code, I automatically grant to you a nonexclusive, irrevocable, royalty-free license to do whatever you want with it, including re-mixing it, re-distributing it under any license you want, or anything else you might think of." Or is this _worse_? Any lawyers in the room? :)
I suppose one could theoretically release something anonymously, but that technically would just be a copyrighted work with an unknown author.
As far as code goes, what's wrong with the MIT license?
Although the WTFPL may have been a joke at first, it is substantially similar to your suggestion. It says, in full:
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim
or modified copies of this license document, and
changing it is allowed as long as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
The WTFPL is recognized as a valid open source license: http://www.wtfpl.net/faq/The same effect seems to be obtained by using the AGPL. Funnily enough, the two licenses at the "extreme ends" of free software elicit exactly the same kind of corporate panic. I always hesitate between these two for my works.
Also I don’t really believe in the concept of authorship, so I want to disavow it as much as possible.
You can do that with the regular shell, just `^Z%; $next_command`, but I agree that nq might be more practical if that kind of workflow is done often.
You can have multiple sessions, give them names, etcetera.
If you accidentally exit the shell with all the jobs, you are done adding jobs to the queue, no?
[edit]
I suppose if you ran nq on boot, it would find the existing queued job files and you would only lose the one running job? Or maybe it would rerun the one that was in progress. Not sure.
2. at and batch have 52 built-in queues: a-z and A-Z. Any directory can be a queue for nq.
3. You can follow the output of an nq queue tail-style with fq.
4. The syntax is different. at and batch take whole scripts from the standard input or a file; nq takes a single command as its command line arguments.
5. nq doesn't rely on a daemon. It's an admirably simple design. Jobs are just flock()-ed output files in a directory.
[1] See https://www.freebsd.org/cgi/man.cgi?query=at&sektion=1&n=1.
[1] https://docs.microsoft.com/en-us/azure/cloud-adoption-framew...
note that many shared filesystems ae not posix-compliant
waitfor() {
while pgrep $1 >/dev/null; do sleep 2; done && $*
} Line 2:
while pgrep $1 >/dev/null; do sleep 2; done && $*
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2048: Use "$@" (with quotes) to prevent whitespace problems.
Also, how do you pick the right job to wait for if several programs match $1? (E.g. if it's a bash script, $1 will be "bash", which on my system matches lots of things.)Also, a 2s sleep will slow things down if you want to use it for a whole lot of jobs.
Also, this won't run your second command if the first command you wait for has already exited!
Also, shouldn't $* be `shift; "$@"` or do you only ever queue jobs of the same command?