Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Replify – Create a REPL for any command (gist.github.com)
112 points by danielrw7 on Aug 19, 2016 | hide | past | web | favorite | 18 comments

Here is my version:

  printf "REPL for %s\n" "$@"
    [ $# -gt 0 ]
  while true ; do
    printf "%s> " "$@"
    read -r || break;
    notblank $REPLY || continue;
    eval command \"\$@\" "$REPLY"
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/replify/replify.sh git
  REPL for git
  git> rev-parse HEAD 
  git> branch -r
    origin/HEAD -> 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.


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

Maybe using rlwrap command would help with the autocompletion and history?

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

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

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.

Another generic `repl` utility, this one in ruby: https://github.com/defunkt/repl

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.

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).

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.

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.

It's likely that with the feature set growing, a version that uses a slightly more advanced language would be easier to maintain and have less "traps" than the bash version...

i actually ported this over to POSIX shell a few years back: https://github.com/joh6nn/shrepl

afaik, it will work just about anywhere you can invoke a shell (i haven't tested it all that extensively)

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

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".

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

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".

This is pretty cool!

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

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact