GitHub - txthinking/jb: jb: write script in an easier way than bash (original) (raw)
jb
= javascript
+ bash
#!/usr/bin/env jb
$`ls -l`
var output = $1`whoami` <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi mathvariant="normal">‘</mi><mi>e</mi><mi>c</mi><mi>h</mi><mi>o</mi></mrow><annotation encoding="application/x-tex">(`echo </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">‘</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span></span></span></span>{output}`)
Bash is great, but when it comes to writing more complex scripts, many people prefer a more convenient programming language. JavaScript is a perfect choice. The jb provides useful wrappers. The jb is a bun port of zx, the advantage is that you don't need to install node, and jb is just a standalone binary.
Install
jb is just a standalone binary, so you can download and put it in your PATH. Or install it via nami
Documentation
Just write your scripts in a file with an .js
Add the following shebang to the beginning of your jb
scripts:
Now you will be able to run your script like so:
chmod +x ./script.js ./script.js
Or via the jb
executable:
Or executes remote script
jb https://www.txthinking.com/script.js
All functions ($
, cd
, fetch
, etc) are available straight away without any imports.
$`command`
Executes a given command, keep the default behavior of stdout and stderr like bash
Or put a variable in command
var name = 'hello' (‘mkdir(mkdir </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.03148em;">mk</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span>{name}
)
You can pass an array of arguments if needed:
var flags = [
'-l',
'-h',
] (‘ls(ls </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">s</span></span></span></span>{flags.join(' ')}
)
If the executed program failed, error will be thrown.
$brook unknownsubcommand
$1`command`
Same as $`command`
, but will return stdout and trim space, as you know, 1 is STDOUT
var count = $1ls -l | wc -l
(‘echo(echo </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">‘</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span></span></span></span>{count}
)
env()
Set env
env('HELLO', "JB") ‘echoecho </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">‘</span><span class="mord mathnormal">ec</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span></span></span></span>HELLO
// => JB
cd()
Changes the current working directory.
cd('/tmp')
$pwd
// => /tmp
question()
var name = question('What is your name? ')
confirm()
var ok = confirm('Do you really want to leave?');
sleep()
now()
Current unix timestamp
echo()
A console.log()
alternative
which()
File path or null
exit()
Exit the script
exists_file()
file exists or not
var yn = exists_file('path/to/file.txt')
read_file()
Read the text from local file
var str = read_file('path/to/file.txt')
write_file()
Write text to local file
write_file('path/to/file.txt', 'some text')
append_file()
Append text to local file
append_file('path/to/file.txt', 'some text')
cp()
Copy file or http file from zip/tar.gz/tar.xz to local
cp('https://github.com/txthinking/brook/releases/latest/download/brook_darwin_arm64', '/tmp/brook');
Copy file from zip
7z l ~/Downloads/bun-darwin-aarch64.zip
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2023-06-03 15:54:41 D.... 0 0 bun-darwin-aarch64
2023-06-03 15:54:41 ..... 46584592 16787941 bun-darwin-aarch64/bun
------------------- ----- ------------ ------------ ------------------------
2023-06-03 15:54:41 46584592 16787941 1 files, 1 folders
cp('$HOME/Downloads/bun-darwin-aarch64.zip', 'bun-darwin-aarch64/bun', '/tmp/bun');
Copy multiple files from tar.gz
tar ztf ~/Downloads/cowsay_2.0.4_macOS_arm64.tar.gz
LICENSE
doc/cowsay.1
cowsay
cowthink
cp('$HOME/Downloads/cowsay_2.0.4_macOS_arm64.tar.gz', { 'cowsay': '/tmp/cowsay', 'cowthink': '/tmp/cowthink', });
Copy multiple files from tar.xz
tar Jtf ~/Downloads/shadowsocks-v1.15.3.aarch64-apple-darwin.tar.xz
sslocal
ssserver
ssurl
ssmanager
ssservice
cp('https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.15.3.aarch64-apple-darwin.tar.xz', { 'sslocal': '/tmp/sslocal', 'ssserver': '/tmp/ssserver', });
Async Functions
stdin()
Returns the stdin as a string.
var s = await stdin()
echo(got ${s} from pipe
);
echo hello | jb ./script.js
retry()
Will return after the first successful attempt, or will throw after specifies attempts count.
var s = await retry(() => $1curl https://www.txthinking.com
)
// delay 1s
var s = await retry(() => $1curl https://www.txthinking.com
, 1000)
// delay 1s and max 3 times
var s = await retry(() => $1curl https://www.txthinking.com
, 1000, 3)
Web, Node, Bun
built-in Web API such as fetch
var res = await fetch('https://www.txthinking.com');
built-in node
import os from 'node:os';
echo(os.homedir());
built-in bun
Bun.serve({ port: 8080, hostname: '127.0.0.1', fetch(req) { return new Response("jb!"); }, });
Executing commands on remote hosts
The jb
uses sshexec to execute commands on remote hosts.
$sshexec -s 1.2.3.4:22 -u user -p pass -c 'ls -l'
Download file from remote
$sshexec -s 1.2.3.4:22 -u user -p pass --download /server/path/to/file --to /local/path/to/file
Upload file to remote
$sshexec -s 1.2.3.4:22 -u user -k path/to/private/key --upload /local/path/to/file --to /server/path/to/file
License
jb itself is MIT-licensed. Refer to the dependencies license for information.