# jupyter_safe_port ``` usage: jupyter_safe_port [-hcdf] {host} [port] Discovers the next TCP port available for your notebook server and returns execution instructions. If the argument '-c' is present and the requested port is already bound on the remote host, return the SSH connection string Positional arguments: host host name or IP of remote system port notebook server port to poll (default: 1024) Arguments: -h show this usage statement -c only generate the SSH connection string -d dump ports (useful in scripts) format: local remote -f apply SSH argument to daemonize session (i.e. ssh -f) ``` ## Install ``` ./install.sh --prefix=/usr/local ``` ## Examples _Oh no! I need to run two notebook servers on a remote system but which ports should I use?_ ``` $ jupyter_safe_port example.lan Execute on example.lan: jupyter notebook --no-browser --port=1024 Connect via: ssh -N -L1024:localhost:1024 user@example.lan ``` You start the first notebook server. Now run `jupyter_safe_port` again... ``` $ jupyter_safe_port example.lan Execute on example.lan: jupyter notebook --no-browser --port=1025 Connect via: ssh -N -L1025:localhost:1025 user@example.lan ``` The local port 1024 is already bound to the first server so it gives you 1025. On the remote system, `example.lan`, port 1024 is bound too so it returns 1025 as well. What if you want to use a higher port number on `example.lan`? Let's see... ``` $ jupyter_safe_port example.lan 8080 Execute on example.lan: jupyter notebook --no-browser --port=8081 Connect via: ssh -N -L1026:localhost:8081 user@example.lan ``` Oops, you forgot about that web server test. 8080 is already bound so you're given 8081 instead. Locally 1024 and 1025 are already bound so `jupyter_safe_port` returns 1026. Let's say you have closed your laptop and lost all of your connections. If you can remember the remote port you used then `-c` will get you up and running in no time... ``` $ jupyter_safe_port example.lan -c 8081 Connect via: ssh -N -L1024:localhost:8081 user@example.lan ``` ## Scripting You can use `jupyter_safe_port` in your scripts. `-d` returns the local port followed by the remote port. ``` $ jupyter_safe_port example.lan -d 8081 1024 8081 ``` Here are a few ways to use it... ```shell #!/usr/bin/env bash if type -p jupyter_safe_port &>/dev/null; then echo "jupyter_safe_port is not installed" >&2 exit 1 fi result=$(jupyter_safe_port -d $server) if [ -z "$result" ]; then # jupyter_safe_port failed # case 1: not enough arguments # case 2: invalid argument # case 3: invalid port range # case 4: ssh failed to connect to $server exit 1 fi # Extract ports from result read $port_local $port_remote <<< "$result" if (( port_remote < 0 )); then { # case 1: no remote ports available # case 2: if using '-c', no service is present on the requested port exit 1 } # Spawn a local screen session to manage a remote jupyter server. # You'd really want to use screen on the remote instead... This is just an example. screen -dmS "jupyter_$server_$remote_port" ssh $server "source ~/miniconda3/etc/profile.d/conda.sh \ && conda activate XYZ \ && jupyter notebook --no-browser --port=$port_remote" # Forward the ports to the local system echo "Forwarding $port_remote to localhost:$port_local" echo "To interrupt the session press: ctrl-c ssh -N $port_local:localhost:$port_remote $server ```