
Show HN: Replify – Create a REPL for any command - danielrw7
https://gist.github.com/danielrw7/bb88e3dad565c0d8ee54031f6b758a09
======
kazinator
Here is my version:

    
    
      #!/bin/bash
      
      printf "REPL for %s\n" "$@"
      
      notblank()
      {
        [ $# -gt 0 ]
      }
      
      while true ; do
        printf "%s> " "$@"
        read -r || break;
        notblank $REPLY || continue;
        eval command \"\$@\" "$REPLY"
      done
    

We keep the original parameters and expand them with "$@". There is a Bash
feature that read with no args reads the line into the REPLY variable. We want
that to be subject to splitting.

If $REPLY expands to nothing, including multiple whitespace, then we just want
to print the prompt again: not quit and not run the command with no additional
arguments.

The eval trick allows $REPLY to undergo expansion and splitting, so that shell
syntax can freely be used in the REPL.

Test:

    
    
      $ ~/test/replify/replify.sh git
      REPL for git
      git> rev-parse HEAD 
      7ac594319e417266764a6bc041b74807f2fe13bd
      git> branch -r
        origin/HEAD -> origin/master
        origin/master
        origin/origin/master
      git> checkout "$TERM $TERM"
      error: pathspec 'xterm xterm' did not match any file(s) known to git.
      git> checkout $TERM
      error: pathspec 'xterm' did not match any file(s) known to git.
    

Cute, but not terribly useful without history recall and related features.
This wants to be a feature of Bash. The regular Bash repl should have a prefix
variable so it can appear to be in a sub-mode for a particular command.

Submit a patch for Bash to do this, and maybe you have something. Bash has a
hook feature for command execution, IIRC, so this may be somehow doable
without modifying Bash.

~~~
Jtsummers
[https://github.com/hanslub42/rlwrap](https://github.com/hanslub42/rlwrap)

EDIT: beat to the punch, should've refreshed.

------
danielrw7
I just found out about a very similar command [1] that has more features.

[1] [https://github.com/mchav/With](https://github.com/mchav/With)

------
continuational
It's only a REPL in the most trivial sense if it doesn't remember variables or
results between commands. I suppose it would be easy to store the output in
$LAST or $R1, $R2, ..., and then eval the input.

------
unfletch
Another generic `repl` utility, this one in ruby:
[https://github.com/defunkt/repl](https://github.com/defunkt/repl)

~~~
Sir_Cmpwn
I find it hilarious that there's a ruby version of a tool that can be
implemented in 10 lines of bash. It's like atwood's law all over again. Use
the right tool for the job, please.

~~~
jbbarth
I'd be happy to see your 10 lines bash version of this ruby tool, with the
same options/properties (debug messages, customizable prompt, history logging,
same safeguards, rlwrap support, man page).

~~~
Sir_Cmpwn
You're missing the point. I could do all of that in a similar (or likely
smaller) number of lines with bash compared to the ruby tool, only mine would
be much faster and wouldn't depend on the enormous ruby runtime.

~~~
joh6nn
the bash version might be technically faster, but i doubt it would be faster
in any practical, meaningful way: most of the time spent in the script is
waiting for input, or waiting for a command to return. that it need not depend
on ruby is a perfectly valid argument though, and is in fact why i bothered
redoing it in POSIX shell.

to do so however didn't just require a similar number of lines, it actually
required 4 more (though to be fair, both scripts have comments and a fair bit
of formatting, so it may not be a fair comparison. also it probably doesn't
need stating, but i'm a bit of a hack, so my implementation maybe shouldn't be
the reference point. but i digress)

in any event, i don't think atwood's law comes into play, given that a) this
isn't in javascript and b) defunkt is a well known member of the ruby
community who spends a lot of time working in ruby and probably wrote this to
actually use it, as quickly as he could think of it. his choice of language
here is perfectly reasonable in that context.

if you remain convinced that the only correct language for such a tool is
bash/shell, i imagine OP certainly welcomes PRs; i know i do.

------
tlrobinson
Related: rlwrap adds some of readline's features like history to REPLs that
don't have those things out of the box.

------
seibelj
Neat trick - the only change I made is to exit the while loop by typing
"exit". That way the enter key runs the command with no arguments, and you can
exit with control+c or by typing "exit".

~~~
Bino
And what if you want "exit" as argument. You should think bigger in general if
your into tooling for others....

~~~
seibelj
Yes, if you have a commonly used command that has "exit" as a commonly used
flag that means something other than exiting, then by all means use something
more specific like "exit2".

------
AlphaWeaver
This is pretty cool!

------
vitoc
This could significantly enhance my Docker in the CLI user experience.

