Seeing And Saying On The Command Line

Occasionally I like command line tools to also say the output, in addition to ‘printing’ it (to STDOUT).

A current context is starting a server locally with updated information. The start up takes time, so I tend to not wait at the command line for it to fully boot.

I wanted a noticeable signal when the thing is up – and also a confirmation that the version of the information source *is* actually updated. The commands tee and (the macOS) say do this for me:

tee >(say&)

tee copies the output of its input to STDOUT (usually the terminal) and the given file. The construction >(other command&) causes tee to send the input not to a file but to othercommand and the & causes that command to return immediately (instead of returning only after the command to finish).

Overall, I do something like this. The system returns a lengthy JSON string, so I use jq to get to the version information I’m looking for:

curl -s -u <username:thepassword> “<url_to_locally_running_service>” | jq “<path_to_version_info_in_json>” | tee >(say&)

The GitHub page explains that

jq is a lightweight and flexible command-line JSON processor.

https://stedolan.github.io/jq/

It’s well worth trying, if you’re dealing with JSON input on the command line.

Passing Multiple Arguments To One Rake Task

Occasionally, I want Rake tasks to take multiple arguments. If the number of these arguments are know beforehand, Rake provides a nice way to express that in the Rakefile (see the Rake documentation for more details).

However, sometimes I like to pass a varying number of arguments the a task, which shall all be processed in the same way. Maybe its user IDs that need to be removed from a database, or a given list of piles to be processed.

Today I found a way to do this, by using Rake::TaskArguments#extras . The method extras returns a list of all the extra arguments passed to a Rake task, that are not named in the task definition. If no argument name(s) are declared in the task definition, then all arguments will be ‘extra arguments’.

An example Rakefile is this:

task :list do |t, args|
  puts "In task '#{t.name}"
  puts 'Passed arguments:'
  puts args.extras.map { |extra| "  * #{extra}" }
end

Calling this task from the command line and its output (in zsh) looks like this:

$ rake list\[one,2,3.141]
In task 'list
Passed arguments:
  * one
  * 2
  * 3.141

Note, the \ before the opening bracket ‘[‘. In zsh, this is needed to escape the ‘[‘ (pairs of ‘[]’ have a special meaning in zsh). Also note, that there are no spaces between the arguments, just the comma.

If you prefer to add a space after the comma, there’s a way to achieve this (again in zsh): Drop the ‘\’ and instead put the task name and the arguments in quotes:

$ rake "list[one, 2, 3.141]"
In task 'list
Passed arguments:
  * one
  * 2
  * 3.141

$ rake 'list[one, 2, 42]'
In task 'list
Passed arguments:
  * one
  * 2
  * 42

In this example it doesn’t affect the output whether single or double quotes are used. Quoting in shells is … complicated, see for example: http://zsh.sourceforge.net/Guide/zshguide05.html#l112.

Did you find this helpful? Or do you know a better way to pass multiple arguments to one Rake task? Please let me know.


Navigation

%d bloggers like this: