CITE THIS NOTEBOOK: ExternalEvaluate Shell: usage examples by Riccardo Di Virgilio. Wolfram Community FEB 15 2023.
I’ve a confession to make, I love the terminal! I must be, because when you are truly in love you can’t explain why you are, you just know you are. It might be because you can do a lot of things without touching the mouse, you can control entire fleets of machines, or simply because when people are looking at you typing into that black windows they think you are a super cool hacker 🥷. However the terminal is far from being perfect, it can do a lot of things with text, but unfortunately it’s really hard to visualize complex data structure or to simply plot a dataset.
I’m one of the main developer of ExternalEvaluate Shell, a new addition to ExternalEvaluate family that allows you to run shell commands in a notebook.
All you need to do is to click on a new cell and click shift + > to start a new cell, type a command and watch the output come out in real time.
〉
In[]:=
hostname
RdvMacbook.local
Out[]=
Success
✓
Command: hostname
ExitCode: 0

Over time I have been able to move some of my favorite automations to notebooks, and they work really nice.

Clone a repo using git

Here is a simple function that allows you to clone a repo if it doesn’t exists on your machine, and keep it up to date with a certain branch.
In[]:=
Block[​​ ​​ url = "https://github.com/hpaluch/rust-hello-world", ​​ dest = "~/Downloads/myClonePath", ​​ branch = "master"​​ ,​​ ExternalEvaluate[​​ "Shell", Flatten @ ​​ If[​​ ! FileExistsQ[FileNameJoin[{dest, ".git"}]],​​ "git clone <* url *> <* dest *>",​​ {}​​ ],​​ "cd <* dest *>",​​ "git checkout <* branch *>",​​ "git pull --all"​​ ​​ ]​​]
Your branch is up to date with 'origin/master'.
Already on 'master'
Already up to date.
Out[]=
Success
✓
Command: cd ~/Downloads/myClonePath
ExitCode: 0
,Success
✓
Command: git checkout master
ExitCode: 0
,Success
✓
Command: git pull --all
ExitCode: 0


Run a rust program from source

Here there is a simple script to automate the download of git repository, build the program from source and run the program. Here I’m assuming the rust and cargo are already present on the machine.
Block[​​ ​​ dest = "~/Downloads/rust-hello-world", ​​ repo = "https://github.com/hpaluch/rust-hello-world.git"​​ ,​​ ExternalEvaluate[​​ "Shell", ​​ "echo 🧹 cleanup the environment",​​ "rm -rf <* dest *>",​​ "echo 🧑‍🔬 download latest code",​​ "cd <* DirectoryName[dest] *>",​​ "git clone <* repo *>", ​​ "cd <* dest *>",​​ "echo 👷‍♀️ build the program",​​ "cargo update",​​ "cargo build",​​ "echo 🚀 run the program",​​ "cargo run"​​ ]​​]
🧹 cleanup the environment
🧑‍🔬 download latest code
Cloning into 'rust-hello-world'...
👷‍♀️ build the program
Updating crates.io index
Finished dev [unoptimized + debuginfo] target(s) in 5.24s
🚀 run the program
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/hello_world`
UTC now is: 2023-01-19 14:56:23.152702 UTC
UTC now in RFC 2822 is: Thu, 19 Jan 2023 14:56:23 +0000
UTC now in RFC 3339 is: 2023-01-19T14:56:23.152702+00:00
UTC now in a custom format is: Thu Jan 19 14:56:23 2023
Out[]=
Success
✓
Command: echo 🧹 cleanup the environment
ExitCode: 0
,Success
✓
Command: rm -rf ~/Downloads/rust-hello-world
ExitCode: 0
,Success
✓
Command: echo 🧑‍🔬 download latest code
ExitCode: 0
,Success
✓
Command: cd ~/Downloads/
ExitCode: 0
,Success
✓
Command: git clone https://github.com/hpaluch/rust-hello-world.git
ExitCode: 0
,Success
✓
Command: cd ~/Downloads/rust-hello-world
ExitCode: 0
,Success
✓
Command: echo 👷‍♀️ build the program
ExitCode: 0
,Success
✓
Command: cargo update
ExitCode: 0
,Success
✓
Command: cargo build
ExitCode: 0
,Success
✓
Command: echo 🚀 run the program
ExitCode: 0
,Success
✓
Command: cargo run
ExitCode: 0


Create a python venv

A tedious task if you work with python is to manage and create virtual environment, in the python ecosystem there are a lot of different tools to manage them, so why not create another one?
In[]:=
Block[​​ ​​ target = "/usr/local/bin/python3",​​ outputFolder = "~/Downloads/myvenv",​​ packages = {"django==4.1.5", "numpy==1.24.1"}​​ ,​​ ExternalEvaluate[​​ "Shell", ​​ "echo 🧹 cleanup the environment",​​ "rm -rf <* outputFolder *>",​​ "echo 🏘 creating venv",​​ "<* target *> -m venv <* outputFolder *>",​​ "echo 🍾 installing requirements",​​ "<* outputFolder *>/bin/python -m pip install <* StringRiffle[packages, \" \"] *>"​​ ​​ ]​​]
🧹 cleanup the environment
🏘 creating venv
🍾 installing requirements
Collecting django==4.1.5
Using cached Django-4.1.5-py3-none-any.whl (8.1 MB)
Collecting numpy==1.24.1
Using cached numpy-1.24.1-cp310-cp310-macosx_10_9_x86_64.whl (19.8 MB)
Collecting asgiref<4,>=3.5.2
Using cached asgiref-3.6.0-py3-none-any.whl (23 kB)
Collecting sqlparse>=0.2.2
Using cached sqlparse-0.4.3-py3-none-any.whl (42 kB)
Installing collected packages: sqlparse, numpy, asgiref, django
Successfully installed asgiref-3.6.0 django-4.1.5 numpy-1.24.1 sqlparse-0.4.3
Out[]=
Success
✓
Command: echo 🧹 cleanup the environment
ExitCode: 0
,Success
✓
Command: rm -rf ~/Downloads/myvenv
ExitCode: 0
,Success
✓
Command: echo 🏘 creating venv
ExitCode: 0
,Success
✓
Command: /usr/local/bin/python3 -m venv ~/Downloads/myvenv
ExitCode: 0
,Success
✓
Command: echo 🍾 installing requirements
ExitCode: 0
,Success
✓
Command: ~/Downloads/myvenv/bin/python -m pip install django==4.1.5 numpy==1.24.1
ExitCode: 0


Plot CPU usage

An advantage of notebooks is that you can easily visualise data, so why not take advantage of it?
Whops, looks like mail is draining a LOT of resources 😵.

To be continued!

I’m just getting started, so stay tuned for more!