Skip to content

rtk bash -c and rtk fish -c wrapping #2767

Closed

Description

@ccoVeille

Sometimes the Agent needs to run command via bash -c or whatever the shell

For example, for running this

head foo && grep -R bar .

It would launch

bash -c "head foo && grep -R bar ."

rtk is able to rewrite the command

$ rtk rewrite 'head foo && grep -R bar .'

rtk read foo && rtk grep -R bar .

But it does nothing when bash -c or fish -c is used

$ rtk rewrite 'bash -c "head foo && grep -R bar ."'

I would expect this to be wrapped

$ rtk rewrite 'bash -c "head foo && grep -R bar ."'

bash -c "rtk read foo && rtk grep -R bar ."

Activity

  1. ccoVeille commented on Jul 1, 2026

    @ccoVeille
    Author

    Here is a piece of code I wrote to fix this, but I would like rtk to support it natively

    Note: I use fish as a shell

    function rtk_wrapper --description "Rewrite-first RTK command router with safe fallback"
        if test (count $argv) -eq 0
            echo "Usage: rtk_wrapper <command ...>" >&2
            return 64
        end
    
        set raw (string join " " -- $argv)
    
        # Special case: shell -c "..." should rewrite the inner script, not only the wrapper command.
        if test (count $argv) -ge 3
            set shell_cmd $argv[1]
            set shell_flag $argv[2]
            if contains -- $shell_cmd fish sh bash zsh; and test "$shell_flag" = "-c"
                set script $argv[3]
                set passthrough_args $argv[4..-1]
    
                set classification (__rtk_wrapper_classify "$script")
                set action $classification[1]
                set value (string join "\n" -- $classification[2..-1])
    
                switch $action
                    case rewrite
                        command $shell_cmd -c "$value" $passthrough_args
                        return $status
                    case deny
                        echo "rtk_wrapper: denied by rtk rewrite policy: $script" >&2
                        return 2
                end
    
                command $shell_cmd -c "$script" $passthrough_args
                return $status
            end
        end
    
        set classification (__rtk_wrapper_classify "$raw")
        set action $classification[1]
        set value (string join "\n" -- $classification[2..-1])
    
        switch $action
            case rewrite
                eval $value
                return $status
            case deny
                echo "rtk_wrapper: denied by rtk rewrite policy: $raw" >&2
                return 2
        end
    
        # Exit 1 (no rewrite) or any unexpected rewrite error: run raw command.
        eval $raw
        return $status
    end
    
    
    # Internal helper: classify command into rewrite/raw/deny based on `rtk rewrite`.
    # Output format (stdout lines):
    #   line 1: action (rewrite|raw|deny)
    #   line 2+: command payload
    function __rtk_wrapper_classify --argument-names cmd
        set rewritten (rtk rewrite "$cmd" 2>/dev/null)
        set rewrite_status $status
    
        switch $rewrite_status
            case 0 3
                if test -n "$rewritten"
                    printf "rewrite\n%s\n" "$rewritten"
                    return 0
                end
            case 2
                printf "deny\n%s\n" "$cmd"
                return 0
        end
    
        printf "raw\n%s\n" "$cmd"
    end
  2. pszymkowiak commented on Jul 1, 2026

    @pszymkowiak
    Collaborator

    wshm · Automated triage by AI

    🔍 Automated Triage

    ✨ Category feature
    🟡 Priority medium
    🎯 Confidence 83%

    Summary

    rtk rewrite does not recurse into bash -c / fish -c quoted arguments; request to rewrite the inner command string rather than silently emit nothing


    Triaged automatically by wshm · This is an automated analysis, not a human review.

  3. pashifika commented on Jul 19, 2026

    @pashifika
    Contributor

    I believe this issue has been resolved by #3057. Please try it and let me know if it works for you.

  4. ccoVeille commented on Jul 19, 2026

    @ccoVeille
    Author

    Thank you @pashifika

    Did you experience a similar issue? Or did you look for issue you could try to fix.

  5. pashifika commented on Jul 19, 2026

    @pashifika
    Contributor

    @ccoVeille
    No, not exactly. I was trying to fix a similar issue where Claude would consistently fail when running rtk run -c '<script>'. I came across this issue while investigating it, and since the underlying cause seemed related, I ended up fixing this one as well.

  6. pavelbe commented on Aug 8, 2026

    @pavelbe

    Retested on rtk 0.45.0 (Linux x86_64 / WSL2, 2026-08-08): the direct shell
    carrier case still does not rewrite in the dry-run.

    rtk hook check --agent claude bash -c 'git status'

    Observed:

    No rewrite for: bash -c git status
    

    The new multiline-block rewrite works for independent newline-separated
    commands, but it does not close this quoted bash -c carrier case. This is only
    a current-version receipt; I am not proposing a naive eval/quote round-trip.
    The existing safety constraints in this issue remain important.

  7. added 3 commits that reference this issue on Sep 2, 2026
    29e56ff
    3317930
    7518b89
  8. added 10 commits that reference this issue on Sep 26, 2026
    e534b67
    0462147
    44e021a
    a05d169
    0d4d832
    12f66a4
    e8ac873
    59c2e4d
    7cc2699
    4d2184c
  9. added a commit that references this issue on Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions