How to Run Bash in Jupyter Notebook
Jupyter Notebook is built for Python, but you can run bash commands too. Here’s how to run bash in Jupyter Notebook using every available method.
Method 1: The ! Shell Escape
The simplest way to run bash in Jupyter Notebook is the shell escape prefix:
!ls -la
!kubectl get pods -n production
!docker ps
Any line starting with ! runs in your system shell.
Capturing Output
Store command output in a Python variable:
pods = !kubectl get pods -n production -o name
print(pods)
# ['pod/api-7d4f8b6c9-x2k4j', 'pod/api-7d4f8b6c9-k8m2n']
Using Python Variables
Pass Python variables to shell commands:
namespace = "production"
!kubectl get pods -n {namespace}
Limitations
- Each
!command runs in a new shell - Environment variables don’t persist between commands
- Can’t run interactive commands
Method 2: The %%bash Cell Magic
For multi-line bash scripts, use the %%bash cell magic:
%%bash
echo "Starting deployment..."
kubectl get pods -n production
kubectl rollout restart deployment/api -n production
echo "Done!"
With Error Handling
%%bash
set -e
kubectl get pods -n production
kubectl rollout restart deployment/api -n production
kubectl rollout status deployment/api -n production
Capturing Output to Variables
%%bash --out output --err error
kubectl get pods -n production
print(output)
print(error)
Limitations
- Still runs in a subprocess
- No interactivity
- The entire cell runs at once—no step-by-step execution
Method 3: The %%script Magic
For specific shells or interpreters:
%%script bash
echo "Running in bash"
%%script zsh
echo "Running in zsh"
%%script sh
echo "Running in sh"
Method 4: Install a Bash Kernel
For notebooks that are primarily bash, install a dedicated kernel:
pip install bash_kernel
python -m bash_kernel.install
Now create notebooks with the Bash kernel. Every cell runs as bash:
# Cell 1
kubectl get nodes
# Cell 2
kubectl get pods -n production
# Cell 3
kubectl describe pod api-7d4f8b6c9-x2k4j -n production
Advantages
- Native bash experience
- Environment variables persist between cells
- Better syntax highlighting
Disadvantages
- Can’t mix Python and bash in the same notebook
- Still requires Jupyter infrastructure
- Not as widely supported
Method 5: Using subprocess
For more control, use Python’s subprocess module:
import subprocess
result = subprocess.run(
["kubectl", "get", "pods", "-n", "production"],
capture_output=True,
text=True
)
print(result.stdout)
if result.returncode != 0:
print(f"Error: {result.stderr}")
With Streaming Output
import subprocess
process = subprocess.Popen(
["kubectl", "logs", "-f", "api-7d4f8b6c9-x2k4j"],
stdout=subprocess.PIPE,
text=True
)
for line in process.stdout:
print(line, end="")
Common Issues When Running Bash in Jupyter Notebook
PATH Not Found
Jupyter may not have the same PATH as your terminal:
import os
os.environ["PATH"] += ":/usr/local/bin:/opt/homebrew/bin"
Or specify full paths:
!/usr/local/bin/kubectl get pods
Environment Variables
Set environment variables for the session:
%env KUBECONFIG=/path/to/kubeconfig
Or in Python:
import os
os.environ["KUBECONFIG"] = "/path/to/kubeconfig"
SSH Commands
SSH can be tricky in Jupyter:
!ssh -o BatchMode=yes user@server "hostname"
Ensure SSH keys are set up for non-interactive authentication.
Interactive Commands
Interactive commands don’t work well:
# This will hang or fail
!vim file.txt # ❌
!top # ❌
!ssh user@host # ❌ (interactive)
When Jupyter Works for Bash
Jupyter is reasonable for:
- Data analysis pipelines with occasional shell commands
- Exploratory work where you’re mixing Python and bash
- Documentation that shows commands and their output
When Jupyter Falls Short
Jupyter isn’t ideal for:
Operations Runbooks
Running bash in Jupyter Notebook for ops work has problems:
- Heavy infrastructure: Jupyter Server, kernels, browser
- No SSH support: Can’t easily run commands on remote servers
- Poor portability: .ipynb files don’t work in standard editors
- Version control noise: Notebook JSON creates messy diffs
Incident Response
During incidents, you don’t want to:
- Start a Jupyter server
- Wait for the kernel to connect
- Navigate cells with a mouse
Team Sharing
Jupyter notebooks require everyone to have Jupyter installed. Markdown files work everywhere.
A Better Way to Run Bash in Notebooks
If you’re learning how to run bash in Jupyter Notebook for DevOps or ops work, consider purpose-built alternatives.
What you actually want:
- Markdown files (not JSON notebooks)
- Step-by-step execution
- SSH support for remote servers
- Works in terminal or browser
- Git-friendly
That’s what Stew provides. Write bash commands in Markdown:
# Restart API
Check current status:
```bash
kubectl get pods -n production -l app=api
```
Restart deployment:
```bash
kubectl rollout restart deployment/api -n production
```
Execute each block independently, see output inline, run locally or over SSH.
Summary
Here’s how to run bash in Jupyter Notebook:
| Method | Best For |
|---|---|
!command | Quick one-liners |
%%bash | Multi-line scripts |
| Bash kernel | Pure bash notebooks |
| subprocess | Programmatic control |
For data science mixed with shell commands, Jupyter works. For operations and infrastructure, there are better tools.
Related Reading
- Beyond Jupyter: better bash notebooks
- Bash in Jupyter for infrastructure automation
- Jupyter notebook bash tips for DevOps
- Jupyter vs executable runbooks for bash
Join the waitlist for Stew—bash notebooks built for ops.