shell
rudof shell starts an interactive REPL. Each line is one of the regular rudof subcommands, without the leading rudof. State loaded by one command (RDF data, a schema, a shapemap, an active endpoint, …) stays loaded for the next command in the same session.
Starting
rudof shell
_ ___
| | / __)
____ _ _ _ | | ___ | |__
/ ___) | | |/ || |/ _ \| __)
| | | |_| ( (_| | |_| | |
|_| \____|\____|\___/|_|
Type 'help' for available commands, 'exit' to quit.
rudof>
Running commands
Same syntax as the CLI, minus the rudof prefix:
rudof> data examples/user.ttl
11 triple(s) loaded
For data, shex, shacl, dctap, pgschema and service — the commands that load a resource and, by default, dump it in full — the shell instead prints a short stats line like this when the line loads something new. This keeps a session that chains several such commands readable, since the full dump mostly just scrolls past. The full dump is still available: give -o/--output-file to write it to a file (see Redirecting one command’s output), or call the command bare afterwards to show what’s currently loaded in full (see below).
A command that hits an internal bug reports it as an ordinary error (Error: ...) rather than crashing the session — the shell keeps running afterwards, with whatever was already loaded still intact.
Multi-line input
If a line ends with an open quote, the shell doesn’t submit it — it keeps reading further lines, shown with a ... continuation prompt, until the quote closes. This lets a multi-line value (e.g. a SPARQL query passed inline to -q) be typed directly at the prompt instead of requiring a separate file:
rudof> query -q 'SELECT ?s ?p ?o WHERE {
... ?s ?p ?o .
... }' examples/user.ttl
If input ends (Ctrl-D) while a quote is still open, the whole pending command is discarded with a warning instead of being misparsed.
Within a line, Ctrl-J inserts a literal newline instead of submitting. This matters when recalling a previous command from history (↑) that already has balanced quoting — pressing Enter would run it immediately, so Ctrl-J lets you keep extending it across more lines first. Alt-Enter does the same in terminals that pass it through, but some intercept it for their own use, so Ctrl-J is the one to rely on.
State persists across commands
Load data and a schema in separate lines, then validate without repeating either:
rudof> data examples/user.ttl
11 triple(s) loaded
rudof> shex examples/user.shex
1 shape(s) loaded
rudof> shex-validate -n :a -l :User
╭──────┬───────┬────────┬───────────────────────╮
│ Node │ Shape │ Status │ Details │
├──────┼───────┼────────┼───────────────────────┤
│ :a │ :User │ OK │ Shape passed :a@:User │
╰──────┴───────┴────────┴───────────────────────╯
A bare command with no arguments shows whatever is currently loaded, in full, instead of erroring:
rudof> data
@prefix : <http://example.org/> .
...
Loading data again: replace, or merge
Unlike the top-level CLI (one data call per process), the shell can chain several data calls in the same session. A second data FILE replaces the RDF/PG data currently loaded, rather than merging into it — this is shell-only behavior, chosen because nothing about data FILE looks additive:
rudof> data examples/user.ttl
11 triple(s) loaded
rudof> data examples/simple.ttl
14 triple(s) loaded
rudof> data
@prefix ... # only examples/simple.ttl's data
Add --merge to merge into the currently loaded data instead:
rudof> data examples/user.ttl
11 triple(s) loaded
rudof> data examples/simple.ttl --merge
25 triple(s) loaded
rudof> data
@prefix ... # both files' data
--merge only exists in the shell, not in the top-level rudof data command.
Bare resource shorthand
For shex, shacl, shapemap, pgschema, dctap, service, materialize, generate, rdf-config, a single argument with no other flags is shorthand for that command’s -s flag. node works the same way with -n, and sparql with -q. This only applies inside the shell.
rudof> shex examples/user.shex
is the same as:
rudof> shex -s examples/user.shex
rudof> node :a
is the same as:
rudof> node -n :a
Redirecting one command’s output
-o/--output-file on a single line writes only that command’s output to a file, the rest of the session still prints to the terminal:
rudof> data examples/user.ttl -o out.ttl
Output saved in out.ttl
Working with a LadybugDB database
connect, ddl, load and query --dialect cypher work in the shell exactly as they do on the command line — no special-casing, since they’re ordinary subcommands like data or shex. ddl is fully stateless (it just prints DDL derived from data given on the line), so it needs nothing from connect first:
rudof> ddl examples/user.ttl --dialect cypher
CREATE NODE TABLE Person (id STRING, knows STRING, name STRING, status STRING, PRIMARY KEY(id));
CREATE REL TABLE knows (FROM Person TO Person);
connect, load and query --dialect cypher, on the other hand, are deliberately stateless too — they don’t share anything through the shell session’s in-memory state (ctx.rudof) the way data/shex/shacl do. Instead connect persists the database path to a connection-details file (.rudof-connection.toml by default), which load and query --dialect cypher then read. That file is exactly what carries the connection from one shell line to the next, the same way it carries it across separate rudof invocations on the command line:
rudof> connect examples/db.lbug
LadybugDB database opened successfully
Path: examples/db.lbug
Connection details stored in '.rudof-connection.toml' (used by `load` and `query --dialect cypher`)
rudof> load examples/user_no_errors.ttl --shapes examples/user_shapes.ttl
Loaded 19 triples from RDF data
...
✓ Load complete!
rudof> query --dialect cypher -q "MATCH (n:Person) RETURN n.name"
Query result (5 tuples, 1 columns):
...
-q/--query takes the query itself, the same flag SPARQL uses — a file, a URL, - for stdin, or (as above) the query text inline; --dialect just says how to interpret it. --db/--connection/--read-only are rejected with an error unless --dialect cypher is given, since they’re meaningless for a SPARQL query.
Because the connection lives in that file rather than the session, reset/reset all has no effect on it — clear it by deleting the file, or point elsewhere with --connection <FILE>/--db <PATH> on a given line.
Selecting a SPARQL endpoint
endpoint shows the endpoint activated in the session, if any:
rudof> endpoint
No endpoint is currently active.
Use 'endpoint NAME' to activate one.
Registered endpoints: DBpedia, UniProt, Wikidata
endpoint NAME activates one of the endpoints registered in the TOML config for the rest of the session. NAME is matched case-insensitively, so wikidata, Wikidata and WikiData all activate the same endpoint — but it’s always reported back using its canonical, registered name:
rudof> endpoint wikidata
Active endpoint: Wikidata (https://query.wikidata.org/sparql)
Commands that query RDF data reuse it without needing --endpoint/-e:
rudof> query -q "select ?label where { <http://www.wikidata.org/entity/Q80> <http://www.w3.org/2000/01/rdf-schema#label> ?label . filter(lang(?label) = 'en') } limit 1"
╭───┬──────────────────────╮
│ │ ?label │
├───┼──────────────────────┤
│ 1 │ "Tim Berners-Lee"@en │
╰───┴──────────────────────╯
See the RDF backend (--backend) reference for how named endpoints are registered.
Registering a new endpoint from a file
endpoint FILE.toml registers a new endpoint from a local TOML file and activates it, instead of activating one already known by name. The file has the same shape as one [rdf.endpoints.<name>] table (see the Config reference) — name, query_url, an optional update_url, and an optional [prefixmap] — and is registered under its own name field:
rudof> endpoint my-endpoint.toml
Registered endpoint 'My Endpoint' from my-endpoint.toml
Active endpoint: My Endpoint (https://example.org/sparql)
This is session-only, like config set — it doesn’t get written back to rudof.toml. Use rudof config -o rudof.toml to save the effective config (now including this endpoint) if you want it to persist.
The endpoints registered by default (Wikidata, DBpedia, UniProt) are themselves just files of this same shape, bundled into rudof at compile time from rudof_rdf/endpoints/ — every *.toml file in that folder is registered automatically, so adding a new one to the defaults (or changing an existing one) is just adding or editing a file there and opening a pull request; no Rust code change needed.
Default prefixes
prefixes manages a list of default prefix declarations for the session. When data (Turtle), shacl (Turtle), shex (ShExC) or query (SPARQL) is loaded, any alias the source text uses but doesn’t declare itself is resolved against these defaults instead of failing to parse. A document’s own declarations always win — a default only fills in an alias the document doesn’t declare. node and shapemap need no separate lookup: they resolve prefixed selectors against whatever prefixmap data/shex already ended up with, so they pick up the same resolution for free.
With no argument, prefixes shows the current default prefix declarations:
rudof> prefixes
No default prefixes are defined.
prefixes add ALIAS IRI adds one (overwriting any existing declaration for that alias):
rudof> prefixes add rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
Added prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
rudof> prefixes
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
If you want to add the default (empty) prefix, use:
rudof> prefixes add "" http://example.org/
Added prefix : <http://example.org/>
prefixes rm ALIAS removes one:
rudof> prefixes rm rdf
Removed prefix rdf
prefixes rename OLD NEW renames an alias, keeping its IRI. prefixes copy OLD NEW adds a new alias for the same IRI, keeping the original alias too:
rudof> prefixes add rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
rudof> prefixes rename rdf rdf1
Renamed prefix rdf to rdf1
rudof> prefixes copy rdf1 rdf
Copied prefix rdf1 to rdf
For example, Turtle data using a p: alias it never declares would normally fail to parse; adding p as a default prefix first lets it resolve:
rudof> data "p:a p:name \"Alice\" ."
Error: Data error: Failed to parse RDF data from 'string' [...]: The prefix p: has not been declared
rudof> prefixes add p http://example.org/
Added prefix p: <http://example.org/>
rudof> data "p:a p:name \"Alice\" ."
1 triple(s) loaded
Resolving a resource argument from a prefix
A resource argument — shex/shacl/dctap/pgschema/service/rdf-config/generate/materialize’s -s (or its bare shorthand), sparql’s -q, shapemap’s -m — can be a prefixed name (alias:local) instead of a full path or URL. It’s expanded against a known prefix before being loaded, the same way es is already bundled with the default Wikidata endpoint (pointing at https://www.wikidata.org/wiki/Special:EntitySchemaText/):
rudof> endpoint wikidata
Active endpoint: Wikidata (https://query.wikidata.org/sparql)
rudof> shex es:E10
3 shape(s) loaded
That fetched https://www.wikidata.org/wiki/Special:EntitySchemaText/E10 — es:E10 was expanded using the active endpoint’s own prefixes. The session’s default prefixes are checked first; the active endpoint’s prefixes (if any endpoint is active) are checked next:
rudof> prefixes add ents https://www.wikidata.org/wiki/Special:EntitySchemaText/
Added prefix ents: <https://www.wikidata.org/wiki/Special:EntitySchemaText/>
rudof> shex ents:E10
3 shape(s) loaded
A value that’s already a URL, an existing file path, -, or whose alias isn’t registered anywhere is left alone and handled exactly as before. node’s identifier argument is deliberately not covered by this — it’s an RDF term reference resolved by the loaded document’s own prefixes, not a resource to fetch.
Clearing session state
reset (no argument, or reset all) clears every piece of session state and starts fresh:
rudof> data examples/user.ttl
11 triple(s) loaded
rudof> shex examples/user.shex
1 shape(s) loaded
rudof> reset
Reset all session state.
rudof> data
Error: Data error: No data loaded: No data loaded
reset TARGET clears only one piece of state, leaving the rest of the session untouched. Targets: data, shex, shex-validation, shacl, shacl-validation, pgschema, pgschema-validation, shapemap, dctap, service, query, sparql, typemap, rdf-config, endpoint. sparql clears just the loaded query text; query clears the loaded query and its results. Give more than one to clear several at once:
rudof> shex examples/user.shex
1 shape(s) loaded
rudof> reset shex
Reset: shex.
rudof> shex
Error: ShEx error: No ShEx schema loaded: No ShEx schema loaded
Data loaded earlier in the same session is untouched by reset shex. Give more than one target to clear several at once, e.g. reset data shex.
The narrow shex/shacl/pgschema targets unload only the schema, leaving any loaded ShapeMap/typemap and validation results alone. The *-validation targets are broader: they clear validation results and unload the associated schema and ShapeMap/typemap together, so a following shex-validate/shacl-validate/pgschema-validate starts from a clean slate.
Running system shell commands
A line starting with ! runs the rest of the line in the system shell:
rudof> !ls examples
Note that !cd DIR only changes the directory of that one-off subshell — it has no effect on the running rudof shell session. Use the built-in cd command below to change the shell’s own working directory.
Changing directory
cd with no argument prints the shell’s current working directory; cd DIR changes it:
rudof> cd
/home/user/project
rudof> cd examples
rudof> data user.ttl
11 triple(s) loaded
Unlike !cd DIR, this changes the actual process working directory, so later relative paths (data FILE, shex FILE, !ls, …) resolve against the new directory for the rest of the session.
Built-in commands
| Command | Effect |
|---|---|
help, ? | List the available subcommands |
exit, quit | Exit the shell |
!<command> | Run <command> in the system shell |
cd [DIR] | Show, or change, the shell’s current directory (affects later relative paths and !<command>) |
endpoint [NAME] | Show the active endpoint, or activate a registered one |
reset [TARGET...] | Clear session state, one or more targets, or everything with no argument |
prefixes [add|rm|rename|copy ...] | Show, or manage, the default prefix declarations |
resolvers [clear] | List built-in external-shape resolver kinds, or reset the session’s resolver chain |
History and completion
Lines are saved to ~/.rudof_history between sessions. Tab completes subcommand names; if several match, they’re all listed on the first Tab (e.g. sh + Tab lists shex, shacl, shapemap, shell, …) instead of silently filling in one. After the first word, Tab completes the endpoint command’s argument against the endpoint names registered in the TOML config — case-insensitively, so wiki + Tab matches Wikidata — and the KEY argument of config get/config set against every dotted key path in the effective config (see the Config reference) — e.g. config get shex_validator. + Tab lists shex_validator.check_negation, shex_validator.width, shex_validator.shapemap, and so on.
For any other subcommand, Tab also completes flag names — shex --viz + Tab fills in --viz-engine — and, for a flag that only accepts a fixed set of values, the value itself, both in long and short form:
rudof> shex --viz-engine <TAB>
graphviz plantuml
rudof> data -r sv<TAB>
rudof> data -r svg
This covers every subcommand’s flags automatically (it’s driven by the same flag metadata --help is), not just the ones with dedicated completion described above. A flag that takes a free-form value instead — a file path, a string — falls back to filename completion, same as any other argument (e.g. config set logging.level’s VALUE is the one exception with its own fixed list: error, warn, info, debug, trace).
Exiting
exit, quit, or Ctrl-D.