Basho evaluates a pipeline of instructions left to right. Instructions can be JavaScript code, reference to an external JS file, or a shell command. To evaluate a JavaScript expression, use the option -j. Let’s start with a single item in the pipeline, a JavaScript constant.
# Prints 100
basho -j 100
# Prints true
basho -j true
# Prints 100
basho -j 10**2
Good news is, the option -j can be omitted for the first expression.
# This works too
basho 100
# Prints 100
basho 10**2
The option -p avoids printing the final result. I am not sure where you'd need to use it, but it's there.
# Prints nothing
basho -p 100
Working with strings is a little difficult. Since bash with chew the quotes for itself. So you’d need to either use single quotes around your double quotes, or just use the -q option for quoting.
# Prints hello, world
basho '"hello, world"'
# Here's a better way to do this
basho -q hello, world
You can pipe an expression into a subsequent expression. The variable ‘x’ is always used as a placeholder for receiving the previous input.
# Prints 10000
basho 100 -j x**2
Execute shell commands with the -e option. The shell command is expanded as a JS template string, with the variable ‘x’ holding the input from the preceding command in the pipeline. Remember to quote or escape characters which hold a special meaning in your shell, such as $, >, <, |, () etc.
# Prints 1000. Escape the $.
basho 1000 -e echo \${x}
You can import a function from a JS file or an npm module with the -i option. The -i option takes two parameters; a filename or module name and an alias for the import. An import is available in all subsequent expressions throughout the pipeline.
# cat square.js
module.exports = function square(n) { return n ** 2; }
# prints 100. Imports square.js as sqr.
basho 10 -i square.js sqr -j "sqr(x)"
# Prints 40000. Does sqr(10), then adds 100, then sqr(200)
basho 10 -i square.js sqr -j "sqr(x)" -j x+100 -j "sqr(x)"
basho can receive input via stdin. As always, ‘x’ represents the input.
# Prints 100
echo 10 | basho parseInt(x)**2
If the input ‘x’ to a shell command is an array, the command is executed for each item in the array.
# echo 1; echo 2; echo 3; echo 4
basho [1,2,3,4] -e echo \${x}
The input ‘x’ can also be an object, which you can expand in the template string.
basho "{ name: 'jes', age: 100 }" -e echo \${x.name}, \${x.age}
You can use an Array of objects.
# echo kai; echo niki
basho "[{name:'kai'}, {name:'niki'}]" -e echo \${x.name}
Array of arrays, sure.
# echo 1 2 3; echo 3 4 5
basho "[[1,2,3], [3,4,5]]" -e echo \${x[0]} \${x[1]} \${x[2]}
A command can choose to receive the entire array at once with the -a option.
# echo 4
basho [1,2,3,4] -a x.length -e echo \${x}
That’s useful for filtering arrays.
# echo 3; echo 4
basho [1,2,3,4] -a "x.filter(x => x > 2)" -e echo \${x}
There’s a shorthand for filter, the option -f.
# echo 3; echo 4
basho [1,2,3,4] -f x>2 -e echo \${x}
There’s reduce too. Here’s the long form.
# Prints the sum 10
basho [1,2,3,4] -a "x.reduce((acc,x)=>acc+x,0)" -e echo \${x}
Shorthand for reduce, the option -r. The first parameter is the lambda, the second parameter is the initial value of the accumulator.
# Prints the sum 10
basho [1,2,3,4] -r acc+x 0 -e echo \${x}
Btw, you could also access an array index in the template literal as the variable ‘i’ in lambdas and shell command templates.
# echo a1; echo b2; echo c3
basho "['a','b','c']" -e echo \${x}\${i}
You can extend the pipeline further after a shell command. The shell command’s stdout becomes the input for the next command.
# echo 110 - which is (10^2) + 10
basho 10 -j x**2 -e echo \${x} -j "parseInt(x)+10" -e echo \${x}
There’s nothing stopping you from using all the piping magic built into your shell.
# Prints 100
basho 10 "x**2" | echo
Promises! If an JS expression evaluates to a promise, it is resolved before passing it to the next command in the pipeline.
# Prints 10
basho "Promise.resolve(10)" -e echo \${x}
# Something more useful
basho -i node-fetch fetch \
-j "fetch('http://oaks.nvg.org/basho.html')" \
-e echo \${x}
Typing basho without any parameters does nothing but might make you happy. Or sad.
basho
Count the number of occurences of a word in a string or file.
echo hello world hello hello | basho "(x.match(/hello/g) || []).length"```
That’s all guys. Report issues or ping me on Twitter.