# How dcg Handles Recursive Shell Analysis for `bash -c` and Inline Code Invocations

> Learn how dcg recursively analyzes shell code for bash -c and inline invocations, scanning inner payloads against destructive patterns for robust security.

- Repository: [Jeff Emanuel/destructive_command_guard](https://github.com/Dicklesworthstone/destructive_command_guard)
- Tags: internals
- Published: 2026-07-13

---

**The dcg (Destructive Command Guard) tool treats arguments of shell code flags like `bash -c` as inline code rather than static data, recursively extracting and scanning inner payloads against the same destructive pattern database used for top-level commands.**

The `dcg` crate in the [Dicklesworthstone/destructive_command_guard](https://github.com/Dicklesworthstone/destructive_command_guard) repository provides robust protection against hidden destructive commands by implementing **recursive shell analysis** that pierces through wrapper invocations. When a command uses inline code flags, dcg extracts the nested script and evaluates it independently, ensuring that dangerous operations cannot evade detection by simply wrapping them in a subshell.

## Detecting Inline Code Flags in Context Parsing

The first step in recursive analysis occurs in **[`src/context.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/context.rs)**, where the parser identifies when a shell is being invoked with a code-execution flag.

### Identifying `-c` and `-e` Arguments

When parsing a command, `Context::extract_inline_code` walks the token list backward looking for known interpreter flags (`-c`, `-e`, `-lc`, etc.). If it finds a match, it records the span of the code argument rather than treating it as benign data:

```rust
// src/context.rs (excerpt)
/// Content of -c/-e flags (bash -c, python -c, node -e).
fn is_argument_data(cmd: &str, flag: Option<&str>) -> bool { 
    // Implementation distinguishes data from code arguments
}

```

This detection is exercised in the test suite ([`tests/security_regressions.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/security_regressions.rs), [`tests/heredoc_pack_gap.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/heredoc_pack_gap.rs)) to ensure that statements like `bash -c "rm -rf /"` are flagged for deeper inspection.

### The `is_argument_data` Helper Function

The `is_argument_data` function determines whether a specific argument position contains executable code or merely data. This distinction prevents false positives while ensuring that the content following `-c` or `-e` is always marked for recursive evaluation.

## Extracting Inner Scripts from Heredoc and Inline Constructs

Once a potential inline code flag is detected, **[`src/heredoc.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/heredoc.rs)** handles the actual extraction of the inner payload.

### Parsing Quoted Payloads

The `extract_inline_code` function in [`src/heredoc.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/heredoc.rs) uses robust pattern matching to capture both double-quoted and single-quoted payloads, including compact forms like `bash -c'rm -rf /'`:

```rust
// src/heredoc.rs (excerpt)
/// `bash -c "code"` → "bash"
fn extract_inline_code(command: &str) -> Option<InlineCodeSpan> { 
    // Regex captures quoted and unquoted inline code
}

```

### The `InlineCodeSpan` Return Type

When a match is found, the function returns an `InlineCodeSpan` struct that points to the inner string (e.g., `"rm -rf /"`). This span includes metadata about the code's position within the original command, enabling accurate error reporting and denial attribution.

## Recursive Evaluation of Extracted Code

After extraction, the evaluator processes the inner snippet as a standalone command.

### The Evaluation Pipeline

In **[`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs)**, the extracted content is passed through the same evaluation pipeline as top-level commands:

```rust
// src/evaluator.rs (excerpt)
let inner = code_span.unwrap().content;
let result = evaluate(inner); // recursive evaluation

```

The same **whitelist** and **blacklist** tables (`SAFE_PATTERNS`, `DESTRUCTIVE_PATTERNS`) are consulted. If the inner command matches a destructive pattern (e.g., `rm -rf /`, `git reset --hard`), dcg produces a denial JSON that references the original outer command but attributes the rule to the inner payload.

### Confidence Scoring for Inline Code

**[`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs)** defines a specific confidence variant for these cases:

```rust
// src/confidence.rs (excerpt)
Self::InlineCodeSpan => "match is in inline code (bash -c, python -c, etc.)"

```

A match inside a `-c` payload receives the `InlineCodeSpan` confidence level, which influences the severity rating and remediation advice. This elevated confidence reflects the higher risk associated with obfuscated commands.

## Blocking Dangerous Commands: Code Examples

### Example 1: Blocking `rm -rf` Inside `bash -c`

The following Rust code demonstrates how dcg blocks a destructive command wrapped in a recursive shell call:

```rust
let input = r#"{"tool_name":"Bash","tool_input":{"command":"bash -c \"rm -rf /\"}}"#;
let output = dcg::run(input); // ← runs the hook
println!("{}", output); // → JSON denial with ruleId = core.filesystem:rm-rf-root

```

**Internal execution flow:**
1. `Context` scans the outer command and identifies the `-c` flag.
2. `heredoc::extract_inline_code` pulls out `rm -rf /`.
3. `evaluator` matches that against the destructive filesystem pattern.
4. A denial JSON is emitted via [`src/output/denial.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/output/denial.rs).

### Example 2: Allowing Safe Commands

Safe commands inside inline code are permitted after evaluation:

```rust
let input = r#"{"tool_name":"Bash","tool_input":{"command":"bash -c \"echo hello\"}}"#;
let output = dcg::run(input); // allowed → no output, exit code 0

```

The same pipeline runs, but the extracted code (`echo hello`) matches only the `SAFE_PATTERNS` whitelist, resulting in silent approval.

## Test Coverage Verification

Recursive shell handling is verified across multiple test files:

- **[`tests/security_regressions.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/security_regressions.rs)**: Confirms `bash -c 'echo {padding}; rm -rf /'` is denied
- **[`tests/heredoc_pack_gap.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/heredoc_pack_gap.rs)**: Validates denial of inner `kubectl delete` commands
- **[`tests/env_s_repro.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/env_s_repro.rs)**: Ensures safe echo inside `bash -c` is not falsely flagged
- **[`tests/codex_hook_protocol.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/tests/codex_hook_protocol.rs)**: Documents support for unwrapped `sh -c` and `bash -c` patterns

These tests exercise the full extraction → evaluation pipeline, guaranteeing that inner dangerous commands are caught even when hidden behind recursive shells.

## Summary

- **Recursive shell analysis** in dcg extracts code arguments from flags like `-c` and `-e` before evaluation.
- **[`src/context.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/context.rs)** and **[`src/heredoc.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/heredoc.rs)** collaborate to identify and parse inline code spans using `extract_inline_code`.
- **[`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs)** recursively evaluates extracted snippets against `DESTRUCTIVE_PATTERNS` and `SAFE_PATTERNS`.
- **`InlineCodeSpan`** confidence scoring in **[`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs)** elevates the severity of matches found inside wrapper commands.
- The guard blocks obfuscated commands like `bash -c "rm -rf /"` while allowing benign inline scripts.

## Frequently Asked Questions

### What shells and interpreters does dcg support for recursive analysis?

According to the source code in [`src/context.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/context.rs), dcg supports the `-c` and `-e` flags for common interpreters including **bash**, **sh**, **python**, and **node**. The `is_argument_data` function recognizes these flags and triggers recursive evaluation for any code arguments that follow them.

### How does dcg distinguish between data arguments and code arguments?

The `is_argument_data` function in [`src/context.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/context.rs) examines the command structure and flag context to determine whether an argument contains executable code. Arguments following known code flags (`-c`, `-e`, `-lc`) are treated as potential code and passed to `extract_inline_code` in [`src/heredoc.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/heredoc.rs) for further parsing, while other arguments are processed as static data.

### Can dcg handle nested recursive calls like `bash -c "bash -c 'rm -rf /'"`?

Yes, the evaluator in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs) calls `evaluate(inner)` recursively on extracted code. If the inner extracted script contains another `bash -c` invocation, the parser will identify the new inline code span and evaluate it again, ensuring that deeply nested destructive commands are detected regardless of obfuscation depth.

### What confidence level is assigned to matches inside inline code spans?

Matches found within `-c` or `-e` payloads receive the **`InlineCodeSpan`** confidence variant defined in [`src/confidence.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/confidence.rs). This specific confidence level indicates that the match occurred inside inline code (such as `bash -c` or `python -c`), resulting in higher severity ratings and more prominent remediation warnings compared to standard top-level command matches.