[HN Gopher] IPython as a System Shell
       ___________________________________________________________________
        
       IPython as a System Shell
        
       Author : laktak
       Score  : 116 points
       Date   : 2021-04-06 13:21 UTC (9 hours ago)
        
 (HTM) web link (ipython.readthedocs.io)
 (TXT) w3m dump (ipython.readthedocs.io)
        
       | ruph123 wrote:
       | I tried this a few years ago when I was younger and more
       | optimistic. But man it was not a great experience.
       | 
       | Having said that I think there is still room for modern shells
       | which are easier to script in. For a while I am using fish and
       | thought scripting would be at least as easy and straightforward
       | as using lua. But the syntax is really awkward. For example
       | comparing two variables needs to be put in a
       | 
       | math "2 + 2"
       | 
       | Urg.
        
       | agumonkey wrote:
       | can't say i don't like the idea, a certain howardism did similar
       | things in emacs org-mode and live document / os code blend feels
       | very right
       | 
       | I can hear the smalltalkers laugh from afar though
        
       | ducktective wrote:
       | - slow startup
       | 
       | - no pipe/redirection mechanism
       | 
       | - high overhead in version/library control(pyenv, venv)
        
         | musingsole wrote:
         | Mostly agree, though if you need piping and redirection, you
         | can use Python for that:
         | 
         | file_list = !ls
         | 
         | delete_me = b[0]
         | 
         | !rm {delete_me}
         | 
         | Though it can't fit into a single statement due to a greedy '!'
        
         | spicybright wrote:
         | - no support for one liners because of python syntax - commands
         | too verbose. a line with two lambda expressions would look
         | terrible
         | 
         | (All my personal preference, obviously. But I'd rather have any
         | other language than python, even lua)
        
           | Pxtl wrote:
           | Lua? Really? My first go-to complaint about Lua is exactly
           | that same one - poor support for lambda-style programming for
           | expressive one-liners.
        
             | spicybright wrote:
             | When I said I'd even take lua over python, that's only if I
             | was forced to pick a high level language for a shell. Lua
             | is really easy to conjure up higher level algos, like
             | javascript can.
             | 
             | But I'm not convinced any high level language is a viable
             | replacement for bash. It would have to be more functional
             | than bash whilst still having good support for standard
             | unix tools.
             | 
             | One very interesting idea I found was a macro library for
             | racket that turns s-expressions from deeply nested
             | structures into a much flatter representation. Lisp might
             | be a good option with toy with because of flexibility like
             | that.
             | 
             | https://www.reddit.com/r/Racket/comments/mands9/fluent_unix
             | _...
        
           | CraneWorm wrote:
           | > But I'd rather have any other language than python, even
           | lua
           | 
           | seriously? lua shell won't even evaluate bare expressions
        
             | boogies wrote:
             | I think you mean lua _jit_ shell?                 $ lua5.3
             | Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio       >
             | 2*3       6            $ rlwrap luajit       LuaJIT
             | 2.1.0-beta3 -- Copyright (C) 2005-2017 Mike Pall.
             | http://luajit.org/       JIT: ON SSE2 SSE3 SSE4.1 AMD fold
             | cse dce fwd dse narrow loop abc sink fuse       > 2*3
             | stdin:1: unexpected symbol near '2'       > =2*3       6
        
       | canjobear wrote:
       | Although I like IPython, I wouldn't want my system shell to be
       | vulnerable to sudden destruction upon updating Python packages.
        
         | stosto88 wrote:
         | Yup
        
       | AzzieElbab wrote:
       | I've been using amm on and off https://ammonite.io/#Ammonite-
       | Shell
       | 
       | pretty nice if you know scala, still have to use regular shell(s)
       | so I do not forget them
        
       | xiaq wrote:
       | If you want a full-fledged programming language in a shell, you
       | might also be interested in Elvish (https://elv.sh). Start with
       | the quick tour: https://elv.sh/learn/tour.html
        
       | dsp_person wrote:
       | I've enjoyed using pyp[1] with fish to make some nice one-liners
       | 
       | For example, custom history command to make early commands at the
       | top, scroll to the bottom, and show the date and command on the
       | same line
       | 
       | function hist; history -t -R | pyp '["\t".join(pair) for pair in
       | zip(lines[::2],lines[1::2])]' | less +G; end; funcsave hist
       | 
       | [1] https://github.com/hauntsaninja/pyp
        
       | vinceguidry wrote:
       | Anyone interested in a Ruby equivalent may like Pry's shell
       | integrations: https://github.com/pry/pry/wiki/Shell-Integration
        
       | stinos wrote:
       | Used this a while ago and it's ok-ish, but I've also used
       | Powershell and despite it not being as nice of a language as
       | Python (imo) and also can suck in other ways, what is striking
       | for this particular example is that Powershell doesn't need most
       | of the explanation on this page because the topic is basically
       | 'here is how to do grep/sed on plain text in a list of strings
       | which contains file information and hope you extract the correct
       | field' and Powershell did nail that pretty well by piping
       | objects.
        
         | 1-6 wrote:
         | Is there a sh to powershell conversion tool? When I run a local
         | environment in Google Colab, I find myself having to write
         | !commands for MS and Linux filesystems. It'd be convenient to
         | write once.
        
           | stinos wrote:
           | Not really (for a couple of often-used commands like cd and
           | ls there are aliases in powershell), but I also wouldn't now
           | how that would work. You mean to convert the complete syntax?
        
       | fredley wrote:
       | > var = !cmd syntax
       | 
       | Is this a standard anywhere outside IPython? I would love to use
       | this sort of thing (python with seamless integration with a
       | system shell) in place of bash scripts. Yes, you can use
       | subprocess but it's a lot less readable.
        
         | mumblemumble wrote:
         | The bang syntax is specific to ipython. I'm not sure it's
         | really desirable outside of that context. It lacks a lot of
         | process control features you'd want in order to make things
         | robust for general purpose scripting purposes.
        
         | neolog wrote:
         | That syntax exists in `git alias` too.
        
         | chrisshroba wrote:
         | It's also similar to a vim construct where prefixing a command
         | with ! makes it run it as an external program instead of a vim
         | command.
        
         | fooblat wrote:
         | While I haven't personally used it, another commenter mentioned
         | Xonsh[0] and that is what it appears to be: A very smooth
         | integration of python into a shell that still feels like a unix
         | shell.
         | 
         | 0. https://xon.sh/
        
         | tyingq wrote:
         | You might like Perl. The syntax to invoke and interact with
         | processes is much more terse than Python's. And there's quite a
         | lot of history of using it instead of shell scripts.
         | 
         | Edit: Things like:                 $output=`ls`;
         | $output=qx#ls -l#;
         | system('/bin/echo','avoid','subshell','invocation');
         | open("APIPELINE","ls -l |");       while (<APIPELINE>) {
         | chomp;          print "Got line: [$_]\n";       }
         | close(APIPELINE);
         | 
         | And access to child exit status in a way that's familiar ($?),
         | etc.
        
           | dale_glass wrote:
           | That Perl is quite out of date.
           | 
           | These days, Perl has 3 argument open, and can use a variable
           | for a filehandle. So:                   open(my $pipeline,
           | "-|", "ls -l");
           | 
           | This is a good thing, because you can treat a filehandle as a
           | standard variable, and can separate the special stuff from
           | the command itself. This way if you're taking in user input,
           | they don't get to mess with that. You can also do:
           | open(my $pipeline, "-|", "ls", "-l", $directory);
           | 
           | Which lets you get away from the mess of correct quoting and
           | just pass every parameter exactly as intended.
        
         | notagoodidea wrote:
         | It depends, for other python REPL/Env not really but it is the
         | standard way to call shell command from ed [1] for example.
         | Julia have also a shell mode in its REPL [2]. Personally, I
         | like to use Raku [3] instead of Python or Shell script. It make
         | it easy to drop one-liner, call shell commands [4] and you can
         | super easily make a script a small CLI utilities by writing a
         | MAIN sub [5].
         | 
         | [1]
         | https://www.gnu.org/software/ed/manual/ed_manual.html#Comman...
         | 
         | [2] https://docs.julialang.org/en/v1/stdlib/REPL/#man-shell-
         | mode
         | 
         | [3] https://raku.org/
         | 
         | [4] https://docs.raku.org/language/quoting#index-entry-
         | quote_qqx...
         | 
         | [5] https://docs.raku.org/language/create-cli
        
       | nickbauman wrote:
       | Babashka has picked up a lot of adherents lately by using a more
       | hybrid approach to this idea. Use clojure to where you want to
       | succinctly and powerfully manipulate data structures (even simple
       | things like (assoc ...) is alien technology in bash) User the
       | shell for everything else.
        
       | jjuel wrote:
       | Couldn't you just use Xonsh?
       | 
       | https://xon.sh/
        
         | geophile wrote:
         | Or take a look at marcel: https://marceltheshell.org
        
         | [deleted]
        
         | chrisweekly wrote:
         | I came here to suggest exactly this.
        
         | ok123456 wrote:
         | xonsh worked poorly with curses based applications when I tried
         | it a while ago.
        
           | BeetleB wrote:
           | I had this problem when I first switched to it, but the
           | solution was in the Github issues. I don't know if it's a
           | problem with the newer releases.
        
           | nyanpasu64 wrote:
           | Last time I tried, it manually "passed through" nano to avoid
           | broken keyboard handling, but you had to add micro, makepkg,
           | sudoedit... to the list, you had to exclude every "top-level
           | binary" that either supplied or invoked a console-based text
           | editor, from xonsh's specialized handling.
        
         | salamander014 wrote:
         | xonsh is absolutely the right way to go here. There are a lot
         | of 'gotchas' when it comes to building a shell that isn't
         | 'just' a novelty but actually usable.
         | 
         | Shells are most successful when you don't need to think in
         | order to use them. Especially since everyone that's used linux
         | in the past 30(?!) years has the same basic foundation for how
         | to use the command line, the best Shell will feel familiar to
         | sh and bash, but better.
         | 
         | Math, logic, string and value manipulation, all those things I
         | need to google because I don't remember whether an if statement
         | in bash needs single [ ] or double [[ ]] or '' or "" or ; or
         | spaces or all those weird gotchas.
         | 
         | I understand that many people do know how to program in bash
         | effectively. That doesn't mean it's the future. It's like the
         | Perl vs Python thread from the other day.
         | 
         | Xonsh is intuitive. Xonsh is well designed. Long live Xonsh.
        
           | craftinator wrote:
           | > all those things I need to google because I don't remember
           | whether an if statement in bash needs single [ ] or double [[
           | ]] or '' or "" or ; or spaces or all those weird gotchas.
           | 
           | This made me chuckle. A few years ago, I went on a learning
           | spree to finally memorize all of these sparse semantics so I
           | could write bash scripts fluently. I ended up having a really
           | good grasp, could write scripts with no flailing.
           | 
           | Six months later, I was back to searching "bash double quotes
           | vs single". Unless you use them every day, for years, these
           | semantics just fall right out of your head.
        
           | Pxtl wrote:
           | Yeah, having played with some scripting-languages-as-shells,
           | the value that a shell adds over REPL is not insignificant...
           | but haphazardly trying to mash together a scripting language
           | and a shell can produce something like Powershell, which is
           | incredibly powerful and expressive but infuriatingly
           | inconsistent and full of gotchas.
        
           | billconan wrote:
           | I'm curious , if I type
           | 
           | "ls -la"
           | 
           | how does it know if it is "variable ls minus variable la", or
           | "command list with command argument -la"?
        
             | jonfw wrote:
             | It checks if the variables 'ls' and 'la' exist, and if they
             | do, it'll run it as python. If not, it'll try to parse it
             | as bash. If it can't parse it as bash, it'll try again in
             | python mode.
             | 
             | https://xon.sh/tutorial.html#python-mode-vs-subprocess-mode
        
               | enriquto wrote:
               | > It checks if the variables 'ls' and 'la' exist, and if
               | they do, it'll run it as python. If not, it'll try to
               | parse it as bash.
               | 
               | This is horrifying. It can break in so many unexpected
               | and context dependent ways... Do people really run this
               | shell on purpose?
        
               | BeetleB wrote:
               | I've been using it for a few years. It has its warts, but
               | the problem you highlighted has never bitten me.
        
             | geophile wrote:
             | In marcel this is a command:                  ls -l
             | 
             | And this is arithmetic:                   (ls -l)
             | 
             | In general, parens delimit arbitrary Python expressions.
             | 
             | https://marceltheshell.org
        
           | cduzz wrote:
           | In shell, "if" just looks at the exit status of the next set
           | of commands.
           | 
           | if ls /path ; then echo foo ; fi
           | 
           | works just as well as the sugar wrapping "test" ( [ ] ) or
           | extended builtins.
        
             | salamander014 wrote:
             | That's fine. But simple things that _should_ work in order
             | to be painless, don 't.
             | 
             | -- -- bash:~]$ if $var < 21; then echo "smaller"; fi
             | 
             | bash: 21: No such file or directory
             | 
             | -- -- BUT this works:
             | 
             | if (( $var < 21 )); then echo "smaller"; fi
             | 
             | smaller
             | 
             | -- -- BUT this DOESN'T:
             | 
             | if [[$var < 21 ]]; then echo "smaller"; fi
             | 
             | bash: 21: No such file or directory
             | 
             | -- -- BUT this DOES (added a space after '[['):
             | 
             | if [[ $var < 21 ]]; then echo "smaller"; fi
             | 
             | smaller
             | 
             | Plus the fact that having to type out 'then' and 'fi' and
             | that semi-colons are semi-necessary are annoying. Compared
             | to today's languages, very little of the non-posix parts of
             | bash feel well though out. We can do better.
             | 
             | All these things make it necessary to understand bash. Most
             | modern programming languages feel familiar. Bash and Sh
             | don't anymore. They feel antiquated.
        
               | cduzz wrote:
               | I'm not defending shell, just pointing out how it works.
               | 
               | One of my biggest annoyances with shell is that there are
               | these magic programs such as [ that pretend to be part of
               | the language but aren't.
               | 
               | If if $var has an exit status (because perhaps you
               | insanely want to have var be some program set elsewhere)
               | your if statement would work....
               | 
               | These other examples have operators (test or similar
               | expanded builtins), and those set the exist status that
               | the if block reads.
               | 
               | so grep -q hacker < /etc/passwd if [ $? -eq 0 ] ; then
               | echo hackd! ; fi
               | 
               | is an indirect way of saying:
               | 
               | if grep -q hacker < /etc/passwd ; then echo hackd! ; fi
               | 
               | Shell is terrible, but the way people use it makes it
               | even worse because the sugar hides what's actually going
               | on.
        
       ___________________________________________________________________
       (page generated 2021-04-06 23:00 UTC)