1. 38
  1.  

  2. 18

    I find polemics like this one to be particularly tired.

    Keypresses, for instance, are roughly as expensive for me now as they were for typists ten or twenty years ago. I am glad that to list files in a directory, I only have to type ls. Critically, however, I do not have any particular expectations of “serious developers”, or any other emotionally loaded stereotypes.

    The flags that a modern BSD-like ls provides are often useful in the “common real-world use cases” that I seem to bump into every day. I am quite satisfied that I do not have to write a small program (functional or otherwise) to have the output of a directory sorted by mtime, or to have colourisation or type sigils included in the output. I’m glad that the recursive mode of GNU grep can descend into a directory tree and emit reasonably structured output: filename on the left, matching text marked in colour on the right. If I had to approach this problem by constructing a new program or pipeline every time, I imagine I would end up writing a new tool which does all the things the current, apparently “bloated”, grep does anyway.

    The terminal emulator I use, iTerm2, is emphatically not a faithful reproduction of a VT100. It is certainly able to speak a reasonable facsimile of the VT100 protocol, but it does so many other things as well. It can, as of late, even display images and 24-bit colour. It turns out that the base abstraction of the serial-attached electric typewriter is quite reasonable, for implementors and users alike. Some ability to use terminal-based software is available on basically every computing platform in existence today, whether small embedded systems or large developer workstations. The whole thing is relatively robust, works without expensive or high-power graphics acceleration, and over low bandwidth network links.

    I think ultimately the Unix philosophy, to the extent that there even is just one, is borne of eminent pragmatism. Continuing to build on existing tools, though without being overly prescriptive to the extent of cargo culting, seems to be working out pretty well. To suggest that something has gone horribly wrong is, as always, to ignore that many people are getting a lot of real work done every day – using any number of descendants and cousins of Unix.

    1. 3

      So, Unix fault is that it’s good enough?

      This is a reference to the art of unix programming chapter about plan 9.

    2. 10

      So… powershell?

      1. 5

        I honestly don’t know how to interpret your comment. As you holding powershell up as an example of the “too many parameters” or as an example of “do one thing well”? I could see an argument for either. I suspect the latter due to powershells “object pipes” (I think that is the name).

        The reason I ask is that with object pipes – you do end up doing one thing at each stage a lot like:

            get-service | where-object {$_.status -eq "running"} | sort-object canstop, displayname | format-table status, name, displayname, canstop
        

        That uses 4 individual commands to generate a nicely printed table. Each part doing one thing well.

        However, you can still see parameter soup on like get-childitem (now I am slightly interested if those features on get-childitem call out to other commands)

            NAME
                Get-ChildItem
        
            SYNTAX
                Get-ChildItem [[-Path] <string[]>] [[-Filter] <string>] [-Include <string[]>] [-Exclude <string[]>] [-Recurse]
                [-Force] [-Name] [-UseTransaction] [-Attributes <FlagsExpression[FileAttributes]> {ReadOnly | Hidden | System |
                Directory | Archive | Device | Normal | Temporary | SparseFile | ReparsePoint | Compressed | Offline |
                NotContentIndexed | Encrypted | IntegrityStream | NoScrubData}] [-Directory] [-File] [-Hidden] [-ReadOnly]
                [-System]  [<CommonParameters>]
        
                Get-ChildItem [[-Filter] <string>] -LiteralPath <string[]> [-Include <string[]>] [-Exclude <string[]>] [-Recurse]
                [-Force] [-Name] [-UseTransaction] [-Attributes <FlagsExpression[FileAttributes]> {ReadOnly | Hidden | System |
                Directory | Archive | Device | Normal | Temporary | SparseFile | ReparsePoint | Compressed | Offline |
                NotContentIndexed | Encrypted | IntegrityStream | NoScrubData}] [-Directory] [-File] [-Hidden] [-ReadOnly]
                [-System]  [<CommonParameters>]
        
        1. 5

          It’s not limited to connecting commands via a stream of text. That seems to be the solution the article is asking for.

      2. 8

        This is an interesting point to start from. Here we have:

        • ls, whose purpose is perhaps to list the files in a directory; the equivalent of os.listdir from Python, or File#listFiles() in Java;
        • -l, -s, and -F, which provide different display formats for each file (which the author thinks is like map, but really in all three cases what you’re displaying is the name and the stat(2) data);
        • -C for grid display, -m for CSV output (what is this useful for?), and -q to quote unprintable characters, specifying different formatting for the output;
        • -r and -t (plus -S, which isn’t mentioned, and the less useful -X and -v) to specify sort order;
        • -a and -R to control which files are included or excluded, which are filters.

        @jclulow says, “I am quite satisfied that I do not have to write a small program to have the output of a directory sorted by mtime.” But of course ls -t is in fact already a small program, written in sh, to spawn a child process executing ls with the argument -t, which does what they want. Of course it would be pretty terrible if you had to write import os; sorted(os.listdir('.'), key=lambda f: os.stat(f).st_mtime) instead of ls -t, even though the ugly Python there does work.

        On the other hand, as the article says, it’s pretty frustrating that -t is not orthogonal to ls or sorting in any way; it must be memorized strictly for the context of sorting ls output by time, and actually it interacts non-orthogonally with -c. If you want to display the mtimes of files, or if you want to compare them, you need to use -l or find -newer. But what if you could type something like “ls^.m”? And what if that displayed as ls '.' ^sortby .mtime, because it introspected the static type of the sequence produced by ls and discovered that mtime was the most frequently invoked existing method on File objects? And what if the tabular output of ls was interactively manipulable in the usual ways that onscreen tables are interactive, plus the ability to feed it as input to something else with a few keystrokes? What if you could include a thumbnail of each file next to the filename?

        What if instead of grep -r RuntimeException . you could say -r % grep RuntimeException, or grep RuntimeException `-r`? The -r command, which is currently called find in Unix, could produce a sequence of file objects, and then grep could produce a sequence of match objects, which you could then reorder: grep RuntimeException `-r` ^sortby .file.mtime. And then maybe you could press a couple of keys to collapse down to just the filename column and eliminate duplicate displayed rows, retroactively giving you -l.

        What if instead of

        get-service | where-object {$_.status -eq "running"} | sort-object canstop, displayname | format-table status, name, displayname, canstop
        

        you could type ls /srv ? run ^.c+.d and get a formatted table with the most commonly viewed fields, incrementally built up and filtered as you type the command? What if the rows of that table were GUI views of the service objects and therefore included “stop” and “restart” buttons, plus a real-time sparkline of the service load?

        I think we could go a long way toward “each program should do one thing well” without compromising usability by improving composability and user interface feedback, especially in 2015 when we can fork tens of thousands of new processes every second if we feel like it.

        I don’t think the VT100 protocol is a good basis for this. Not even if you add SIXEL graphics to it.

        1. 5

          I am always terrified when people suggest “most used” as a default. ^r to mean reverse is all good until one day it means remove. And then… Lollerskates.

          1. 2

            Yeah, there needs to be a balance there. I think having immediate visual feedback can mitigate this to some extent, and I was thinking that ^ would always mean “sort by”, so there’s no danger of irreversible side effects from that.

          2. 3

            I think you’re conflating a lot of different things, here. For instance: the language you’re using to communicate with the computer, and the transport and display technology that you’re using to present the computer’s reply.

            I am not at all frustrated that ls -t emits the text that I’m actually looking for, rather than some stream of object data that I subsequently need to format for output and tabulate. It is possible to over-generalise, to the extent that you produce a facility that is cumbersome to use, or which has frankly paltry ergonomics.

            Some new ideas actually provide material benefits over old ones. For instance, producing logs in a machine-readable format such as the linefeed-separated JSON records emitted by node-bunyan allows for many useful facilities. You can filter on specific named properties without constructing fragile regular expressions, or aggregate a particular field (e.g. response latency) over a large number of log records to see distributions and patterns.

            It is of vital importance, though, that tools like bunyan build on the existing solid primitives we use all the time: text flowing through pipes, output to terminals, and so on. You can also take the log data and put it through analysis/indexing tools, or even display it in web interfaces or other visual tools – but these things are in addition to, rather than instead of the tools we have that are already working quite well.

            I really do not want to replace the terminal I have now with something that sounds, basically, like a web browser. If you want interactive, visual layouts with all of the properties of a modern GUI application that’s great – but it emphatically does not replace the terminal. Chief among the benefits of the existing terminal interface (both model and protocol) is its simplicity, and whatever magical post-modern application you’re describing here does not even seem vaguely adjacent to simplicity.

            As I said above, it is possible (perhaps even easy) to over-generalise. You could write a new grep that is capable of providing structured output records rather than formatted terminal output. You could write a new ls that produces structured records describing each directory entry, rather than format them for humans to read. But Unix systems host a range of different software, written in a range of different languages and using a range of different IPC mechanisms – that’s part of the charm! The likelihood that you’re going to be able to produce some uniform, object-structured, IPC mechanism and rewrite every program in existence to speak it is slim.

            If you want a better file management program, go and write that. Blow the world away by doing that one thing well. To the extent that it can be composable with other programs through some IPC mechanism that’s great, but recognise that some of the most breathtaking advances in software engineering have come from constructing software as larger, better-integrated systems of software. The best example I can think of is ZFS, which replaces the traditional volume manager and filesystem split with one (larger) subsystem, and is eminently more reliable and useable as a result.

            1. 4

              Edited to add: I realize now that my response below is more a response to your bizarrely patronizing and aggressive tone than to your actual substantive points; I shouldn’t have replied in kind, but I did. I need to think more about your substantive points.

              I think you’re conflating a lot of different things, here. For instance: the language you’re using to communicate with the computer, and the transport and display technology that you’re using to present the computer’s reply.

              The existing system conflates these; I am proposing to separate them. Also, your response conflates the shell with the terminal, and I don’t think that’s necessary; I think we can separately replace the shell and the terminal with better software, at different times.

              Chief among the benefits of the existing terminal interface (both model and protocol) is its simplicity,

              I’m going to go out on a limb here and predict that you can recite from memory neither the rules for terminal wrapping, nor the order of stages of substitution in bash. (Quick, does parsing into words come before or after variable interpolation?) It’s easy to think that systems we don’t understand are simpler than they are.

              While I agree that VT100+bash is better than the nightmare of needless complexity and ridiculous inefficiency that is the modern web browser, or for that matter X11 or OpenGL, that doesn’t mean it’s some kind of optimum. We’ve been using it in its current form for more or less 30 years, and during that time we’ve learned a lot of things we could do better.

              The likelihood that you’re going to be able to produce some uniform, object-structured, IPC mechanism and rewrite every program in existence to speak it is slim.

              This is the actual chief benefit of the existing terminal interface: it’s compatible with some existing software, and it’s relatively versatile.

              But we can do better. A lot better.

              1. 1

                Somewhat related, showing a crude prototype of some interesting ideas, is the TempleOS thread.

          3. 5

            Rob Pike and friends would argue BSD is what went wrong, but GNU is went it had absolutely no regard for anything anymore. Look at GNU echo, with all the longopts.

            1. 2

              This whole article made me think it was 1983 again… http://harmful.cat-v.org/cat-v/

              1. 1

                It’s interesting how Rob Pike said BSD was not 10x better, yet OpenBSD, from what I’ve gathered, is a lot more secure than any other operating system out there right now.

            2. 3

              One of the reasons I like OpenBSD is that the developers maintain a strong (but not necessarily complete) adherence to POSIX.

              1. 1

                The Unix-Haters rings as true as ever.

                1. 6

                  Except their options are gone. Macs, while still friendly, are now UNIX. VMS is deader than a doornail. Windows is the only reasonable option left for UNIX haters, and that has problems of its own.

                  1. 1

                    Well, they could port plan 9 userspace over to the linux or any bsd kernel…

                    1. 6

                      Most of the traditional haters (of the UNIX Haters' Handbook) hated UNIX and its concepts - Plan 9 took the concepts to the extreme, and to them, would be even worse

                      1. 1

                        Haiku on linux? ;)

                      2. 1