Hacker News new | ask | show | jobs
by amiga386 5 days ago
I'd be jumping out the top storey window after about 2 minutes of being required to use Python as a shell.

Python is a full-on programming language. Its REPL is a REPL for that language. Interacting with the OS and filesystem is a niche, tucked away in a corner of the language.

It has has none of the ergonomic affordances needed to be the user interface for interacting with files and processes.

Here are some simple commands:

    ls
    cd foo
    ls
    rm bar
    cd ../baz
    rm bar
    echo >readme.txt baz directory
    curl -s http://example.com >download
Let's try doing that with python:

    python
    >>> ls
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'ls' is not defined
    >>> import system
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'system'
    >>> import os
    >>> os.dir.list()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'os' has no attribute 'dir'
    >>> help(os)

    >>> os.listdir()
    ['foo', 'bar', 'baz']
    >>> cd foo
      File "<stdin>", line 1
        cd foo
           ^
    SyntaxError: invalid syntax
    >>> chdir("foo")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'chdir' is not defined
    >>> os.chdir("foo")
    >>> os.listdir()
    ['bar']
    >>> os.delete("bar")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'os' has no attribute 'delete'
    >>> os.remove("bar")
    >>> os.chdir("../baz")
    >>> os.remove("bar")
    >>> f = open("readme.txt", "w")
    >>> f.write("baz directory")
    13
    >>> f.close()
    >>> import process
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'process'
    >>> import subprocess
    >>> subprocess.run("curl", "-s", "http://example.com/")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/subprocess.py", line 505, in run
        with Popen(*popenargs, **kwargs) as process:
      File "/usr/lib/python3.9/subprocess.py", line 778, in __init__
        raise TypeError("bufsize must be an integer")
    TypeError: bufsize must be an integer
    >>> subprocess.run(["curl", "-s", "http://example.com/"])
    ...
    CompletedProcess(args=['curl', '-s', 'http://example.com/'], returncode=0)
    >>> subprocess.run(args=["curl", "-s", "http://example.com/"], capture_output=True)
    CompletedProcess(args=['curl', '-s', 'http://example.com/'], returncode=0, stdout=b'...\n', stderr=b'')
    >>> p = subprocess.run(args=["curl", "-s", "http://example.com/"], capture_output=True)
    >>> fh = open("download", "w")
    >>> fh.write(p.stdout)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: write() argument must be str, not bytes
    >>> fh = open("download", "wb")
    >>> fh.write(p.stdout)
    559
    >>> fh.close()
1 comments

Yes, someone who has no idea how to use their shell and tries to get around by making arbitrary guesses will suffer. This is true for bash as well. It's no reason to kill yourself immediately.
I put it to you that a "shell" that does not natively run the executable programs you type is a non-starter as a shell.

I would be ready for the window if I had to type

    import subprocess; p = subprocess.run(args=["curl", "-s", "http://example.com/"], capture_output=True); fh = open("output", "wb"); fh.write(p.stdout); fh.close()
rather than

    curl -s http://example.com/ >output
There are certainly attempts to create a shell that's powered by Python and allows the Python language into it, but one could not "largely replace bash with the Python REPL". Only people who didn't want a shell in the first place would think that reasonable.
I think we're talking past each other. You are largely not understanding the point I'm saying. I agree that Python, as a shell and scripting language, will have different ergonomics and tradeoffs compared to Bash.

The point I am making is that, of the listed languages, Python is far more comparable to Bash than the others. Suppose you had no choice but to use one of the following executables in place of /usr/bin/bash

- go - gcc - rustc - node - python

You would choose Python, of course. Plausibly node, but certainly not any of the other three.

OK, but you to admit "largely replace bash with the Python REPL" is something of a stretch.

I didn't read the list of languages given by the earlier poster as specific list, I read them as "<list of random programming languages that aren't shells>". And sure, a scripting language is closer to a shell than a compiled language, but I wouldn't say either Python or Node treat shell commands as first-class citizens, as fellow scripting languages Perl and Ruby do... and even the I wouldn't use Ruby or Perl REPLs as shells, because they're still actually programming languages, not text-based user interfaces to your OS.

    Perl:   $x = `ls -l`;
    Ruby:   x = `ls -l`
    Python: import subprocess; x = subprocess.run(args=["ls", "-l"], capture_output=True).stdout
    Node:   let x = (await require('util').promisify(require('child_process').exec)("ls -l")).stdout