Claude Code is an AI coding agent from Anthropic that runs in a terminal. It
can read your project, propose edits, and run commands that you approve. This
page runs it on an Euler compute node reserved by a Slurm job, inside tmux
(a program that keeps a terminal session alive after you disconnect). Your
session survives a closed laptop or a dropped SSH connection.
Goal: start Claude Code on a Slurm compute allocation, detach and reattach safely, and give it the lab rules as context.
Prerequisites:
- The final public-key-only
config-okalias test in Euler access passes. - GitHub access from Euler works, as in step 2 of GitHub code sync. You need it to clone the onboarding repository in step 4.
- You have a Claude account that includes Claude Code (Pro, Max, Team, Enterprise, or Console). The free plan does not include it. Lab-funded access follows the internal lab handbook. Read Personal AI accounts and costs before you pay for anything yourself.
- You have read the AI coding agents boundaries and the Data and AI policy. Use only data that the information owner has approved for this service.
New to text commands? Read how to open a terminal and run one command first.
Execution context: every block on this page runs on an Euler login node -
Bash (after ssh euler), unless the heading says otherwise. Claude Code
itself runs on a compute node that claude-start reserves for you.
Understand Before Accepting AI Output#
- Human intent: you decide the task. Claude Code proposes; you approve.
- Context: step 4 points Claude Code at the lab rules in this repository.
- Constraints: do not let it submit Slurm jobs, start GPU work, install software, commit, or push unless you asked for that exact action.
- Verification: read every command before you approve it. Read every diff before you stage it.
- Review criteria: you must be able to explain each accepted change and each submitted job request in your own words.
1. Install Claude Code#
The eth_proxy module gives Euler nodes access to the internet. Login nodes
usually have access already. Compute nodes need the module.
module load eth_proxy
curl -fsSL https://claude.ai/install.sh | bash
grep -qxF 'export PATH="$HOME/.local/bin:$PATH"' ~/.bashrc || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
grep -qxF 'module load eth_proxy 2>/dev/null' ~/.bashrc || echo 'module load eth_proxy 2>/dev/null' >> ~/.bashrc
source ~/.bashrc
claude --version
Expected output: the last line prints a version number such as
2.1.211 (Claude Code). The installer puts the program at
~/.local/bin/claude. You can run this block again safely. It does not add
duplicate lines to ~/.bashrc.
2. Log In Once#
claude
Type /login, open the link in the browser on your computer, and paste the
code back into the terminal. When Claude Code shows its prompt, type /exit.
Log in only. Do not start real work on the login node. Login nodes are shared by all Euler users.
3. Install The Helper Commands#
This block writes three commands to ~/.claude-euler.sh and loads that file
from ~/.bashrc:
claude-startreserves a compute node and opens Claude Code on it.claude-listshows your running Claude Code jobs.claude-reconnectattaches to a running job again.
The defaults are small on purpose: 2 CPU cores, 4 GiB per core, 2 hours, on
es_fuge. You can run this block again to update the file.
cat > ~/.claude-euler.sh <<'CLAUDE_EULER'
# Claude Code on Euler helpers. Source: IDEAL Lab onboarding,
# docs/reference/euler/claude-code.md
claude-start() {
local gpu=false time_hours=2 account=es_fuge
local usage="Usage: claude-start [--time HOURS] [--account es_fuge|public] [--gpu]"
while [[ $# -gt 0 ]]; do
case $1 in
--gpu) gpu=true; shift ;;
--time)
if [[ $# -lt 2 || ! "$2" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
echo "STOP: --time needs a number of hours, for example 1.5"; echo "$usage"; return 1
fi
time_hours=$2; shift 2 ;;
--account)
if [[ $# -lt 2 || ! "$2" =~ ^[A-Za-z0-9_]+$ ]]; then
echo "STOP: --account needs an account name, for example es_fuge"; echo "$usage"; return 1
fi
account=$2; shift 2 ;;
*) echo "$usage"; return 1 ;;
esac
done
if $gpu && [[ "$account" == "public" ]]; then
echo "STOP: the public share has no GPUs. Use --account es_fuge for --gpu."
return 1
fi
local mins
mins=$(awk -v h="$time_hours" 'BEGIN { printf "%d", h * 60 }')
if [[ "$mins" -lt 1 ]]; then
echo "STOP: --time must be a positive number of hours, for example 1.5"
return 1
fi
local time_fmt
time_fmt=$(printf "%02d:%02d:00" $((mins / 60)) $((mins % 60)))
local name="ccc_$(date +%H%M)"
local opts=(--cpus-per-task=2 --mem-per-cpu=4G)
if $gpu; then
name="ccg_$(date +%H%M)"
opts=(--cpus-per-task=4 --mem-per-cpu=4G --gpus=rtx_4090:1)
fi
local logdir="$HOME/.claude-euler-logs"
mkdir -p "$logdir" && chmod 700 "$logdir"
local jobid
jobid=$(sbatch --parsable --account="$account" --job-name="$name" \
--time="$time_fmt" --output="$logdir/%j.out" "${opts[@]}" <<'JOB'
#!/bin/bash -l
module load eth_proxy || exit 1
sock="job_$SLURM_JOB_ID"
tmux -L "$sock" new-session -d -s claude "claude" || exit 1
while tmux -L "$sock" has-session -t claude 2>/dev/null; do sleep 10; done
JOB
)
if [[ -z "$jobid" ]]; then
echo "sbatch failed"
return 1
fi
echo "Job $jobid ($name, $account, $time_fmt). Waiting for a node..."
while true; do
local state
state=$(squeue -j "$jobid" -h -o "%T" 2>/dev/null)
if [[ "$state" == "RUNNING" ]]; then
claude-reconnect "$jobid"
return
fi
if [[ -z "$state" ]]; then
echo "Job ended or was cancelled"
return 1
fi
sleep 2
done
}
claude-list() {
squeue -u "$USER" -h -o "%i %j %T %M %R" | grep -E "^[0-9]+ cc[gc]_" || echo "No claude jobs"
}
claude-reconnect() {
local jobid=$1
if [[ ! "$jobid" =~ ^[0-9]+$ ]]; then
claude-list
return 1
fi
local state node
read -r state node < <(squeue -j "$jobid" -h -o "%T %N")
if [[ "$state" != "RUNNING" || -z "$node" ]]; then
echo "Job $jobid is not running"
return 1
fi
for _ in $(seq 1 20); do
ssh -t "$node" "tmux -L job_$jobid attach -t claude" 2>/dev/null && return 0
sleep 2
done
echo "Failed to attach"
return 1
}
CLAUDE_EULER
grep -qxF 'source ~/.claude-euler.sh' ~/.bashrc || echo 'source ~/.claude-euler.sh' >> ~/.bashrc
source ~/.bashrc
type claude-start >/dev/null && echo "OK: helpers installed"
Expected output: OK: helpers installed.
4. Give Claude Code The Lab Rules#
Claude Code reads ~/.claude/CLAUDE.md at the start of every session. This
step clones this onboarding repository to your Euler home and points that file
at the repository's agent instructions and linked research briefing. The
reference asks Claude Code to read the relevant lab rules rather than copying
them. Follow Give your AI agent the lab context for
project instructions and the fresh-session check; a reference alone does not
prove that the files were read.
The repository is private to the IDEAL Lab GitHub organization. If the clone
fails with Repository not found, ask lab IT for access.
(
cd "$HOME" || exit 1
if [ -d "$HOME/onboarding-IT/.git" ]; then
git -C "$HOME/onboarding-IT" pull --ff-only
else
git clone git@github.com:IDEALLab/onboarding-IT.git
fi
)
If step 2 of GitHub code sync made you create the dedicated Euler key, run this clone instead:
(
cd "$HOME" || exit 1
GIT_SSH_COMMAND="ssh -i $HOME/.ssh/id_ed25519_github_euler -o IdentitiesOnly=yes" git clone git@github.com:IDEALLab/onboarding-IT.git || exit 1
git -C "$HOME/onboarding-IT" config --local core.sshCommand "ssh -i $HOME/.ssh/id_ed25519_github_euler -o IdentitiesOnly=yes"
)
Then add the pointer to your personal Claude Code instructions:
mkdir -p ~/.claude
grep -qF 'onboarding-IT/AGENTS.md' ~/.claude/CLAUDE.md 2>/dev/null || cat >> ~/.claude/CLAUDE.md <<'CLAUDE_MD'
# IDEAL Lab rules
- Before any lab operation on Euler (Slurm jobs, storage, GitHub, Python
environments, Weights & Biases, Hugging Face), read
~/onboarding-IT/AGENTS.md and the research briefing it links to.
- Do not submit Slurm jobs, start GPU work, install software, commit, or push
unless I ask for that exact action in this session.
CLAUDE_MD
tail -n 8 ~/.claude/CLAUDE.md
Expected output: the last lines of ~/.claude/CLAUDE.md show the
IDEAL Lab rules section once. Run the first block again from time to time to
get current lab rules.
5. How Do I Use It?#
Start a session. The command waits until Slurm gives you a node, then opens Claude Code:
claude-start --time 1.5 # 1.5 hours on es_fuge
claude-start # 2 hours (default)
claude-start --account public --time 1
Use --account public only for CPU work that fits the
public-share limits.
GPU sessions are for short, approved debugging only. Ask your supervisor first.
Use sbatch for training. See the GPU rules.
claude-start --gpu --time 0.5 # one RTX 4090, 30 minutes
Detach (Claude Code keeps working): press Ctrl-b, release both keys, then
press d.
Reattach later:
claude-list
The first column is the job ID. Pass it to claude-reconnect, for example:
claude-reconnect 12345678
Stop: type /exit in Claude Code. The job ends when Claude Code exits or
the time runs out. To stop a job that you cannot attach to:
scancel 12345678
Data, Jobs, And Sessions#
These pages are the canonical lab procedures for data, code, and jobs:
- Move files and choose storage: Storage and data lifecycle.
- Move code between your computer, GitHub, and Euler: GitHub code sync.
- Write and submit batch jobs: Slurm job lifecycle.
The research briefing named in step 4 already links to these procedures. Use the lab-context guide to verify that your session reads the briefing and the files relevant to its task. You do not need a second copy of the procedure list in your instructions.
Claude Code saves each conversation under ~/.claude/projects/, in one folder
per working directory. In the same directory, claude --continue opens the
most recent conversation and claude --resume shows a list.
Common Failures And Safe Recovery#
claude: command not found: runsource ~/.bashrc. If that does not help, run the step 1 block again.ECONNREFUSEDor no network inside Claude Code: the compute node did not loadeth_proxy. Check that~/.bashrccontainsmodule load eth_proxy 2>/dev/null.claude-startwaits a long time: the job is pending. Runclaude-list; the last column shows the reason. See pending reasons.Job ended or was cancelled: runsacct -j 12345678with your job ID and read the state. Then read the job log, for examplecat ~/.claude-euler-logs/12345678.out.Failed to attach: Claude Code may have exited on the node. Runclaude-list. Cancel the job withscancelif it still runs, then start a new one.- Session crashes with
Bus error: your Euler home is network storage shared by all nodes. An automatic update on another node can remove the program version that this session uses. Start a new session. - Claude Code asks to log in again: run
claudeon the login node, type/login, then/exit.
Primary Sources#
Verified: 2026-10-08. Review by: 2027-01-06. Owner: IDEAL Lab IT.