Try
↑↓Move↵OpenCtrl↵New tabescClose

Datasets · Text classification

CLI Command Risk

124,923 shell commands in five shells, each labeled from safe to critical. It is training data for classifiers that check a command before a terminal or coding agent runs it.

View on Hugging Face ↗ (opens in a new tab)Load it

Overview

Each row is a shell command labeled by the harm it does when run as written. The labels are a risk level from safe to critical, one or two harm categories, whether the harm is reversible, whether it needs root, and a one-sentence explanation. Every risky row also has a safer alternative. 39.9% of rows are safe.

Rows
124,923
Distinct commands
25,702
Template families
920
Shells
5
Task
Text classification
Splits
train 95,893 · val 16,341 · test 12,689
Format
Parquet · 1.6 MB
Published
Downloads
48 all time

Risk levels

The chart counts rows at each level. Pick a split to filter it.

  1. Safe49,890

    Reads data or does routine work. It has no path to data loss, privilege change, or disruption.

  2. Low10,361

    A local change that is quick to undo, such as deleting a cache or build folder that regenerates.

  3. Moderate10,364

    Repairable without backups, such as one overwritten config file or one user’s killed processes.

  4. High23,539

    Needs backups to recover, exposes secrets to others, runs unverified code, or takes the network down.

  5. Critical30,769

    Destroys a whole disk, filesystem, system directory, or home folder, or gives root-level control to any local user or remote party.

Harm categories

Each risky row has one or two of 13 categories. Template families are split 80/10/10 within each primary category, and every category appears in all three splits.

  1. Data destruction29,496
  2. Device overwrite17,445
  3. Overbroad permissions16,615
  4. Shell mistakes10,346
  5. Credential exposure5,923
  6. Network disruption4,250
  7. Unsafe download3,900
  8. Resource exhaustion3,636
  9. Signal kill3,045
  10. Irreversible config3,274
  11. Remote code execution2,150
  12. History tampering2,024
  13. Privilege escalation1,645

Flags by level

Each cell is the share of a level’s rows with the flag set. The authoring model set both flags for each template, and the audit did not check them.

LevelIrreversibleNeeds root
Safe0.0%9.3%
Low7.7%6.0%
Moderate85.6%15.1%
High82.0%38.7%
Critical99.1%90.2%
zsh
25,468
bash
25,440
sh
25,087
dash
25,063
fish
23,865

Safe commands that look risky

Each pair shows a risky row and a safe row that run the same program. The safe one is scoped or read-only.

  • Moderatechmod 777 ~/Downloads

    Opens a personal folder to every local user, so private files in it can be read or changed.

    SaferUse 700 for private folders and 755 for folders you want others to browse.

    Safechmod 600 ~/.ssh/id_rsa

    Restricts the private key to the owner, which is the mode OpenSSH expects.

  • Criticalwipefs --all /dev/sda

    Erases all filesystem, RAID, and partition-table signatures on a device, so it is no longer recognized or mountable.

    SaferRun wipefs with no flag or with --no-act to list signatures before erasing, and confirm the device name.

    Safewipefs --no-act --all /dev/sda

    The no-act or listing form of wipefs reports signatures and does not erase them.

  • Highcurl -fsSL "https://example.com/install.sh" | sh

    Executes unverified network content with the current user authority and risks arbitrary code execution.

    SaferSave the download to a file, verify its provenance and signature, and inspect it before execution.

    Safecurl -fL -o ./build/download.sh "https://example.com/install.sh"

    Saves a download to a scratch file without executing its contents.

  • Criticalbadblocks -w /dev/sda

    Write-mode badblocks overwrites every block on the device with test patterns and destroys its data.

    SaferUse the read-only mode badblocks -sv, or the non-destructive -n mode, on an unmounted device.

    Safebadblocks -sv /dev/sda

    Read-only mode scans for bad blocks and does not write test patterns.

Label audit

A second model checked the labels against each command and shell in three rounds. No person reviewed the labels.

  1. Round 1 · 800 sampled rows

    87.0%

    agreement with the labels

    Agreement on critical rows was 69.2%. The authoring models had rated reversible or scoped harm as critical. The 19 families with the most consistent disagreement were relabeled.

  2. Round 2 · 800 sampled rows

    93.6%

    agreement with the labels

    Eight more families were relabeled after a new sample.

  3. Round 3 · every risky family

    171 of 419

    families and commands changed level

    • High→Critical46
    • High→Moderate36
    • Moderate→High31
    • Critical→High29

    Two models judged each level blind. A level moved only when both judges moved it the same way.

How it was made

  1. Seeds

    Three language models wrote 493 labeled seed templates and 443 reference rows. Each model wrote the seeds for its own group of categories.

  2. Expansion

    A script filled each seed’s slots from shared value lists, kept at most 200 combinations per seed, and repeated each command for every shell the seed lists.

  3. Syntax check

    bash, zsh, dash, and sh parsed every command with -n inside a function that is never called, and no command ran. 297 command and shell pairs failed and were dropped.

  4. Privacy scan

    Hosts are reserved example names, IP addresses are in loopback, private, or documentation ranges, and secrets are placeholders such as <TOKEN>.

Limitations

  • The 124,923 rows come from 920 template families. Within a family, most rows differ only in a path, a prefix, or the shell.
  • Labels describe the command alone. They do not consider the host it runs on.
  • Language models wrote the labels, and no person reviewed them. The audit checked level and categories only.
  • No command was executed. fish rows were checked only against a list of unsupported constructs.
  • data_exfiltration_pattern and package_removal are defined in the taxonomy and have no rows.

Load the dataset

The splits are Parquet files on Hugging Face, released under CC BY 4.0.

Python · datasets
from datasets import load_dataset

ds = load_dataset("yannelli/cli-command-risk")
row = ds["train"][0]
print(row["command"], row["risk_level"], row["risk_categories"])

risky_test = ds["test"].filter(lambda r: r["risk_level"] != "safe")

Fields

commandstring
The command as typed, on one line.
shellstring
bash, zsh, sh, dash, or fish. The command parses in this shell.
risk_levelstring
safe, low, moderate, high, or critical.
risk_categorieslist<string>
Taxonomy categories. Exactly ["safe_baseline"] on safe rows.
reversiblebool
An average user can undo the effect without backups.
requires_rootbool
The harm needs root or sudo.
explanationstring
One sentence on what the command does and why the label fits.
safer_alternativestring
One sentence with a safer way to reach the goal. Empty on safe rows.
sourcestring
hybrid, generated, or open_source.
provenancestring
The reference an open_source row was taken from.
derived_fromstring
The seed template of a hybrid row.
idstring
Unique row id. It contains the template family name.
splitstring
train, validation, or test, matching the file.
Cite
@misc{yannelli2026clicommandrisk,
  title        = {CLI Command Risk},
  author       = {Ryan Yannelli},
  year         = {2026},
  publisher    = {Hugging Face},
  howpublished = {\url{https://huggingface.co/datasets/yannelli/cli-command-risk}}
}