Why then isn't a kind of very simple approximation of a GUI (or, at least, easily-discoverable commands) more common in command line applications? I see no technical reason for the lack of it. Look at something like htop -- it has a sort of "command line version of a macOS menu bar" with each menu selected by a function key. I could easily seeing this idea being extended to, say, being called by the familiar --help flag, or each menu visualizing a sub-menu upon pressing a function key, etc...there's no reason CLIs can't have the same discoverability as GUIs.
That CUA was originally defined for text-mode applications as well, and indeed was based on loose conventions that had emerged within IBM for text-mode applications, has been largely forgotten. But even in the '80s there was an appreciable divide between the IBM paradigm, which was more oriented towards menus and actions (what we think of as GUI today), and the AT&T/UNIX paradigm, which was more oriented towards composition of commands.
Of course there are things like newt which have crossed the lines, but generally speaking UNIX derivatives such as Linux have tended to "stay in their lane" of command-oriented environments with minimal user assists. This could be seen as a long-lasting influence of the different I/O paradigms these platforms tended to feature in the influential '80s: UNIX systems were built around line input and output (e.g. TTYs) while IBM systems of the same era were more often built around video terminals (e.g. CRTs). This was basically because UNIX was predominantly running on hardware of opportunity (e.g. whatever the institution already had), and thus had to be flexible and not assume much, while IBM systems were more often used with terminals leased from IBM along with the machine and thus could assume the latest era of video terminal capabilities.
And then, of course, sometime around the '90s all of these platforms more or less ossified in their differences from each other, as each respective camp came to view their UI paradigm as a core feature of the platform which should not be modified.
This is just one of the ways in which UNIX and its family are much more "line-oriented" than even many of their contemporary competitors. This was partially by necessity but also partially by design as the line-oriented paradigm was easy to understand and work with, conceptually if not in practice. Ironically line-oriented input and output is often justified as being reminiscent of punched cards, when the software lineage with a far longer background in punched paper media (IBM, CDC, etc) were far quicker to get away from this model of human-computer interface than UNIX.
Put more generally, "GUI" vs "TUI" is to some degree a false dichotomy. Many of the real capabilities and interactions we associate with GUIs are also quite possible in TUIs (although the GUI version is clearly a refinement), and indeed were often implemented prior to the common availability of raster displays. When people talk about "GUI" vs "TUI" they are almost always actually talking about differing fundamental UI paradigms, which I might call action-oriented and line-oriented. Each can be implemented in a raster-mode or text-mode environment, although both generally work better in a raster-mode display (we might consider Jupyter to be an example of a line-oriented paradigm on a raster display).
On one axis we have graphical (raster mode) at one end and text at the other. On the other we have as you calld them action-oriented (WIMP) and line-oriented (I would call it command-oriented).
There are text mode action-oriented apps: ncurses/turbo vision/etc. based applications like *Commander, or the old Borland IDE, or Tilde, or the old FoxPro, or plenty others.
And there are graphical command-oriented apps like Jupyter or ReGIS or Sixel or iTerm or TermKit or Kui or the command palette in VSCode or Atom or others.
And you can have them mixed like in youtube-dl GUI or ffmpeg GUI where the changes you make in the GUI are reflected in different arguments for the command and you can see and edit the command before executing it. This is similar to getting keyboard shortcut suggestions in menus or tooltips.
We need more innovation in this space. Ways to achieve both discoverability and scriptability. We need more hybrids and less systems that stay in their lane. Graphical text editors with command pallettes, PowerShell with its object oriented piping, Jupyter are moves in this direction.
This is a power user direction. And it is opposed both to the minimalist touch friendly trend and to the terminal-first mindset.
These are graphical programs, just with a substandard drawing api.
They are not graphical programs. They are generally recognised as TUI programs. If these are graphical then so is Vi or the fancy powerline prompt.
Our point was that you can also have command lines in graphical applications and WIMP in text mode applications.
How should we classify the following?
- Programs like coreutils that receive arguments and return a result
- Programs that start a menu or wizard in text mode
- Programs that start a interactive command line like various database CLI interfaces, shells
- Programs like Vim that have a TUI and are command line driven.
- Programs like Tilda that have a WIMP TUI
I think the last four have graphical equivalents (eg. Windows installers, Jupyter, VSCode, Notepad++ respectively) and what is missing is a graphical interface for passing arguments to programs.
The mark of a command line is a stream of commands and responses, not whether it does ascii art to emulate graphics.
I do agree with your definition of a command line interface as a stream of commands and responses.
On IBM i (originally known as OS/400), you can press a function key and automatically get a fill-in-form for any command.
This is because command line syntax is defined, not in your program's code (getopt calls etc), but using declarations in what you might consider to be a separate command definition file (technically called a "*CMD object"). The OS does command line parsing and validation, marshals the result into a memory block, and passes that to your program rather than the raw command line. And the OS uses the same command syntax declarations to generate the (text mode) fill-in form for display.
Other systems which use the idea of command line syntax declarations, with the shell doing option parsing based on those declarations instead of each program doing them itself, include OpenVMS DCL and PowerShell. (PowerShell actually copied this idea from OpenVMS DCL and IBM OS/400.)
I think the big reason why this is less common in Unix-like systems, is the design decision to give each command responsibility for parsing arguments/options, rather than doing it in the shell. This makes the whole approach of automatically generating fill-in forms at the worst impossible, at the best unreliable. You can try parsing --help output or man pages, but that method isn't always going to work, centralising option parsing in the shell does. It is likely rather too late for Unix-like systems to change their approach.
File explorer multi pick is the thing I desperately claw for for a pointer.
Compare that to most GUI apps where you can just open and use and learn as you go.
Now a TUI isn't the same as command line and most GUIs allow for substantial keyboard functionality, but I think developing for a TUI tends to get you thinking about a person working a keyboard whereas developing a GUI you're thinking more about the person with a mouse/trackball/trackpad/touchscreen.
Personally, I do a lot of database work; mostly PostgreSQL. I decided some years ago to bite the bullet and get rid of the GUI and just use straight psql. I largely haven't looked back, though if I'm doing heavy development work I just started using DataGrip since it helps avoid stupid errors that a simpler text editor doesn't find.
Having said that, I think that the inertia of "good enough" is a real danger to the concept. The new user that uses the less efficient GUI aspects of the interface to learn quickly may not have much incentive to go the next step and work the keyboard oriented workflow into their muscle memory. Also, if you realize that issue, there's also the problem that if the keyboard interface were less used, there would be less incentive to fix issues or add features to it as the application changed. Rightfully, it could become less useful because of less attention. I can tell you that in practice I find it fairly uncommon to see staff using the keyboard capabilities insofar as it's already supported by their GUI applications.
The nice thing is that by using the keyboard to navigate menus, you develop muscle memory for "shortcuts" without really trying. And if you ever get "stuck", not knowing how to complete the sequence, you only have to look at the currently open menu.
Formica doesn't do this, but this could be extended into rudimentary scripting.
This kind of paradigm won't fit all software, for example I don't think it's a good fit for software where typing mildly structured text is the main mode of interaction. It might be mainly useful for shortcut-heavy software.
[0]: The software in question: https://www.formica.cz/
This worked surprisingly well. New users mostly stuck to the menus to discover things, but then gradually switched over to commands for common actions, because they were faster. It also helped that the Command window had context-sensitive help, so once your menu action generated the corresponding command, you could easily open the manual page for it to read up on the details.
PS scripts (and even functions) declare command line arguments up front, and depending on how much time and thought you put into it, you can constrain the arguments quite well. See [0] for overview of the available functionality. A quick TL;DR:
- You can make parameters typed, and PS will handle relevant conversion if the user just types strings in. E.g. you can mark a parameter as [DateTime], and if the user types e.g. "2021-04-01", the script will receive an object that represents the midnight on that day. If the user types in "foobar" instead, they'll get an immediate error[1] telling them the parameter cannot be read as a date.
- Add [] to parameter type (e.g. [DateTime[]] instead of [DateTime]), and now the parameter can accept multiple values (arrays), - but behaves smartly if only one is given.
- You can mark parameters as mandatory. You can mark parameters as positional (i.e. provided without specifying parameter name on invocation). You can mark a parameter as designated "catch-all". You can define aliases for parameters, to allow user to write e.g. -Runs, -Run or -R, and have all three refer to the same parameter.
- You can mark parameters as "accepting values from pipeline" (and define how exactly). Since PS pipes transport typed objects, not raw bytes, this is how you can both set expectations, and write scripts that can flexibly mix pipes with commandline arguments.
- You can define validation for every parameter individually.
- You can group parameters into sets, based on what other parameters are provided, or some custom logic. So e.g. if arguments -A and -B only make sense together, and then -C doesn't do anything, you can encode this cleanly.
- Autocomplete in PowerShell is aware of all these things! It'll hint you appropriately. And you can provide your own autocomplete hints too.
How is all that relevant to this thread? The last point is a spoiler: all these declarations can be extracted from the script, and they provide enough information to build a high quality GUI for the script automatically. PowerShell ISE, that comes with Windows, exploits this to a limited degree - it contains a GUI for running PS cmdlets that lists parameters and their types, makes use of optional/mandatory status, and groups them by parameter sets. There's nothing stopping one from building an equivalent UI generator that would also provide custom widgets based on argument types (e.g. file pickers for paths, calendars for DateTimes, etc.).
--
[0] - https://docs.microsoft.com/en-us/powershell/module/microsoft...
[1] - Errors in PowerShell are a bit user-unfriendly. Niceties like invocation with underlined mistake are surrounded by long error text and small stack trace. I wish they improved on that; even for script developers, most of the error message is quite useless.
PS C:\> 1/0
Attempted to divide by zero.
At line:1 char:1
+ 1/0
+ ~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
is now: PS C:\> 1/0
RuntimeException: Attempted to divide by zero.
And everywhere else they've tried to make a shorter, clearer default error.TypeScript is not yet expressive enough for direct shell usage, but not much is missing imo (most importantantly a pipe operator).
But I get it. It's the consequence of trying to use the same language for code and command line input. > and < are already used in pretty much every single shell to indicate IO redirection; particularly with >, it would be really dangerous for it to have context-dependent meanings. And then foo -match bar is more CLI-input-friendly than foo.match(bar) or match(foo, bar). You can get a similar experience if you try to use (or design) a Lisp shell. S-expressions are awesome, but having to move the caret back and forth to add/modify structure in your command is too annoying for a shell language. For shells, you essentially want as much appending and as little editing as possible.
And as much as I don't like JavaScript ecosystem, I would like something like TypeScript in the shell. Personally, my main requirements are 1) optionally typed, and 2) piping structured data instead of unstructured text/byte streams.
(And then I'd like a terminal emulator that makes full use of type system in pipes and command arguments.)
--
[0] - They started simple, then they grew, and before I noticed, they've crossed the threshold where, if I were to write them again, I'd use a regular programming language. I think the point in which I started including bits of C# code in the scripts should've been a wakeup call... but on the other hand, isn't it just cool you can drop down to C# in the middle of a script and have it Just Work?
When the sorts of things that pgcli does becomes most helpful is when I'm writing functions and procedures, but then the command line isn't well suited for that. That's where I'm finding something like DataGrip helpful: a database tool focused on development rather than administration. DataGrip has a lot of faults, but for the past couple of weeks I've been using it, it's been on balance a win.
This is generally true of built in Windows applications (even if the transition to ribbon interfaces complicated flows). It is spotty for third party applications.
Unfortunately on Linux, at least on KDE (I don't like Gnome since v3), keyboard navigation is broken even on default applications like Dolphin or Discover.
Mac OS, I remember (Tiger -Lion) being pretty good.
i use ssms for mssql, and i have a large solution with multiple projects
i know datagrip can be used in the same way as ssms, but can you this be done using psql
\set show_slow_queries
'SELECT
(total_time / 1000 / 60) as total_minutes,
(total_time/calls) as average_time, query
FROM pg_stat_statements
ORDER BY 1 DESC
LIMIT 100;'
(got from https://www.craigkerstiens.com/2013/02/21/more-out-of-psql/)and then later at the command prompt you access it as; ":show_slow_queries".
I have a few system queries like this in my .psqlrc file, but I don't do much which this feature often truth be told. I have a pretty strong knowledge of the database schema I work with, I do a lot of work on systems I don't regularly control so its not dependably available, and readline history suffices for more immediate needs.
You know the secrets on how to use the Microsoft Windows 95 GUI so it's easy for you. Consider the person who has not been trained over years in its use. The concept of a context menu that pops up at the mouse position when clicking button number two is not intuitive or discoverable.
My wife, for example, grew up before Windows 95 and its descendents were invented, holds multiple post-secondary degrees, and works with computers every day. She has no idea a second mouse button exists let alone that she can use it to perform file manipulation operations. She doesn't quite get the idea of "home directories" or "nested folders" or anything that is hidden like menus (or, frankly, tabs in the browser.. or multiple browser windows in fullscreen mode). Those things are not intuitive or discoverable in any way if you haven't been trained in their use. I, too, often forget the context menu is there although with practive I'm getting better. I certainly would never forget the `df` command though because it's second nature to me after over 40 years of use.
People need to be very careful when making an argument that something is better because it's what they're familiar with as if they are some definitive exemplar.
Once you've figured out that mouse movements correspond to moving the pointer, clicking your left button usually means you want to do the primary interaction with whatever you're clicking on (opening a program, pressing a button, checking a checkbox), and right click gives you additional things you can do with the thing you're right clicking on, you've figured out enough to be able to at least use the system (I agree you're by no means proficient in it though).
To get comparable proficiency with a command line requires a much larger set of things to remember for even basic usage.
That is not the argument they made, they said right-click acts as a "tell me what I can do with this file" discoverability tool, not that right-click is itself discoverable. There is approximately no way to discover this on a command line, but if you right-click and "play with Windows Media Player" is there, it tells you something useful.
But I'm going to make the argument that it is discoverable. Why isn't the context menu second nature to you after over 25 years of use? You put your hand on the mouse, it has two buttons, you click one of them in ordinary operation, what kind of hyperbole is it to say that "clicking the second button does things" is "not discoverable in any way"? You discover that by accidentally mashing it one day, if nothing else.
it's easy because MS has spent years in formal user studies for almost every element of the 95 UI to make sure that it was easy for pretty much everyone.
Cosmetic differences in CLI applications are actually important to get them to work in the first place. dash vs double dash, equals sign or no equals sign. CLI parsing is completely nonstandardized. Each command reinvents parsing and is completely unpredictable.
The only way you could possibly solve this is by letting the shell parse CLI arguments and just pass them as a JSON like object to the application. The ship for that has sailed a long time ago.
What if there was such a thing as a right click menu for command line programs?
Like if I type ffmpeg or youtube-dl with no args, it lists the 3 most common ways to use it, and maybe allows an interactive CLI menu where you can build up the correct argument list by answering a few questions.
I would love the most useful commands to look like:
ffmpeg --resizeVideoTo input.mp4 50% (0.5 also works of course)
youtube-dl --do-the-thing-you-know-i-want-to-do <YOUTUBE_URL>
cd --show-a-menu-of-the-last-10-paths-i-changed-to
git --i-fd-up-my-last-commit-please-help
Most realistically, I'd want the invocation without arguments to show an interactive menu of the top 3 uses, so I could just select what I want to do.Or if I provide a partial argument list, it should ask me to supply the rest of the args. Or maybe it should guess and do the right thing.
For example:
ffmpeg input.mp4
>> What would you like to do with input.mp4? 1) resize 2) rotate 3) crop 4) change video format
youtube-dl URL
>> Download the best video for URL to the current path? Press Enter to confirm.
cd
>> Here are the last 5 paths you switched to. Choose 1...5.
find
>> Start typing a partial file name and we will show the top 10 matches from this path and its subdirectories. CTRL-<period> to turn on regular expression search. curl cheat.sh/ffmpeg
curl cheat.sh/youtube-dl
curl cheat.sh/cd
curl cheat.sh/find
It gives quite a bit more than 3 use cases, but you could do: curl -s cheat.sh/ffmpeg | head
For more details you can go to the site in a browser or use: curl cheat.sh
curl cheat.sh/:help function cheat() {
curl cht.sh/$1
}So perhaps a suggestion could be to install tldr so as to be able to call a summary in your terminal without the need for web-access to cheat.sh
ffmpeg--resize-video video.mp4 50%
.bashrc:
ffmpeg--resize-video() {
ffmpeg ... "$1"
}
You'll have added benefit that ffmpeg--<TAB> will suggest you only your own UI, without interference from the tool's own options.This doesn't help when you want to map the fuzzy idea of performing a specific action to a particular existing program but it has helped me avoid having to search online for how to perform a particular task with ffmpeg.
[1] https://tldr.sh
However I think the tldrs need to be sorted better. When tldr git, the first example was
Check the Git version: git --version
Shouldn't the tldrs show me how to add, commit, push? Who knows.I think the tldr lists should be interactive and allow you to select by pressing 1-9.
And maybe it should re-sort based on what you use most often, hehe.
tldr git commit
will show examples and explanations for using `git commit`.I like the 3 top uses.
As for questions, maybe when I write:
ffmpeg gui
I'll get a gui menu where I can select all the options, and that will generate a textual command for me that I could use further.
The hard part of course is creating GUI's for all the console apps.
Can that be done mechanically?
PowerShell does this, but PowerShell is mostly despised by Linux users on forums.
When I enabled tab completion for git and google cloud CLI, my life became much better.
However, I still think there needs to be a "right click menu" for command line programs. Someone needs to determine the 3 most common uses and make it so that --help lets me choose one of them by pressing 1, 2, or 3.
Right now, --help usually gives me something that is difficult for me to understand, especially if I have never used that command before.
Tab completion works great if I have used the command before and want to save time.
Tab-completion could additionally list the "most common things given the context* I have".
Tab-completion needs not nessecarily be postfix. I've seen completion tooling** that would work somewhat like `invoice.pdf<tab> -> `open invoice.pdf\n cp invoice.pdf` etc.
And if `<tab>` conflicts, or breaks your mind because it must only work on postfix, it could be anything really, such as `<cmd>-r`.
Additionally, or underlying, a reasonable simple command like `whatcan` or `ctxt` (context) could work and be leveraged: `whatcan invoice.pdf` -> a list of common commands given the context* I have.
---
* Context I have would be your ~.\_history, the current directory-tree, permissions (why show `mv` if you don't have write access?), applications available, etc. pluggable maybe?
** e.g. the <ctrl>-r, interactive bash history search come to mind as pattern. But also tools like FZF https://github.com/junegunn/fzf#fuzzy-completion-for-bash-an... that don't nessecarily only "complete" on tab, but may replace larger parts of the commandline.*
Edit: formatting.
You can do that locally on the command line too!
apropos apropos
if you forget that apropos apropos apropos
Recursion solves every problem;-)More seriously: You can alias it to something you can remember, for example:
alias help=aproposThere are a small number of seed keywords which are ueeful to know. 'help' (shell), 'apropos', 'man' (online manual), 'info' (GNU documentation), and dwww (local documentation presented through a Web interface, available on Debian-based Linux, see https://ostechnix.com/dwww-view-complete-debian-documentatio...) are among them.
Knowledge requires a certain baseline.
If that's too much ... perhaps a GUI is in fact advisable.
disk space: nothing appropriate. catman -w
just once to (re)build the index. Results are guaranteed to be of high quality only on a real UNIX, preferrably one of open source Solaris (illumos) distributions, and likely FreeBSD.$ apropos "disk space"
df (1) - report file system disk space usage
$ man -k "disk space"
df (1) - report file system disk space usage
and
$ man -k "disk usage"
docker-system-df (1) - Show docker disk usage
All the pre-Web UI patterns start to shine when you're working with more powerful software tools - where there are more than half-dozen available actions, so you can't just stuff them under a single hamburger list. You have to start categorizing, grouping actions by their commonalities. You can't sort by importance, because importance changes from minute to minute.
And menus of old were plenty discoverable. They weren't categorized for discoverability, because that's not the job of categorization. If you want to discover what the software can do, you spend 60 seconds expanding every single menu and reading available options. The categorization is there to introduce grouping concepts that are easy to remember, so that next time you're looking for an action you know (or suspect) exists, you know where to look for it.
Also, compared to the others you mentioned, hamburger menus are the most discoverable.
I think the main issues of usability are paradigm-independent—how do you make the UX more discoverable for text interfaces? How do you make the GUI more powerful and accessible to scripts? GUI development was introduced to make computers more tactile, and feel more life-like and accessible; and it works.
The reason Text-UIs work better for automation is that programming languages these days are text-based. How might one shift to a more graphical-programming paradigm? Machine learning I think has a lot of potential in this area and I would love to see some new work in this space.
$help
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
That last sentence in particular.I'd try "ls /bin" and see if any of the names sounded familiar or possibly relevant. Or "man -k space" which shows "df (1) - report file system disk space usage" on line 24, which isn't a lot of reading.
GUI's aren't always intuitive. Nothing worse than not having the option in your right-click menu because you tried right-clicking in the left "explorer" column, but really needed to open the parent dir then right-click on the folder in the right-hand side. GUIs can be infinitely more difficult/complex.
Back in the Win95 days, I recall a case where someone couldn't figure out how to format a floppy. After struggling for hours, he did a search which found format.exe, and used it. It's hard to discover that you can right-click on the drive to get the option, because there are many things that don't show up there... You can't create partitions or change drive letters in the right-click menu there, for example, but how would you know? You've got to learn the options/capabilities for your system, whether its GUI or CLI.
What a GUI really has going for it, is that it offers a limited set of options, greatly simplifying the exploration. Something like Norton Commander, DOSBox or other limited/restricted shell (which shows only the most common commands) has similar discoverability benefits without the graphics, and still with those cli benefits available to you.
On a real UNIX like HP-UX, IRIX, Solaris, FreeBSD or illumos (and any of its distributions), you'd run catman -w as root only once for the lifetime of the system, then run:
man -k "disk space"
and then you'd search for SEE ALSO with "/", eventually you'd run into df(1), under the very bad presumption that it isn't the first hit. EXAMPLE (Solaris 10, identical for illumos / SmartOS)
> man -k "disk space"
cfsadmin cfsadmin (1m) - administer disk space used for caching file systems with the Cache File-System (CacheFS)
df df (1b) - display status of disk space on file systems
df_ufs df_ufs (1m) - report free disk space on ufs file systems
snmpdf snmpdf (1m) - get a listing of disk space usage on a remote machine by means of SNMP
space space (4) - disk space requirement file
df df (1) - report file system disk space usage
df df (1gnu) - report file system disk space usage
...on a real UNIX, manual pages are THE resource, they are very comprehensive because they were written by professional documentation departments, respectively professional technical writers in those departments working with the actual engineers who developed the software.The manual page system on a real UNIX is designed to locate exactly the type of information you would be looking for quickly, efficiently and most importantly, consistently.
It's GNU/Linux manual pages that are utter garbage, ergo switch to a system like SmartOS and never look back.
Yes, we get it, you hate Linux. Your user profile page says as much. Get over it.
I think that's more a design-problem than actual trait of GUIs. GUIs have evolved that way, but there is no reason why they can't support composing and interoperability too. MacOS, KDE and Web-UI showed how it's possible to do. It's just that nobody ever went to the full way to build a GUI-Framework from ground up that is reaching the same level of automation as shells.
> TUI/console is very good for interoperability/automation/muscle memory,
TUI and console is not the same. TUI is a GUI inside the terminal, thus usually only with text. Vim, emacs, mc or any curses-app is an example of TUI. And how well can you automate and support interoperability with them really? As I know, all the automation and interoperability comes from the devs adding it on purpose, it's not there by design, or as easy as with a shellscript.
> If I don't remember the `df` command... what do I do apart from searching on the internet? Maybe searching man pages, but it isn't as fuzzy (e.g. `man -K "free space"` isn't very fruitful). In comparison, I know that if I start going through GUI, eventually I'll eventually find the free disk space info.
To be fair, GUIs can also have complex workflows and undiscoverable features. It's just common sense that GUIs have menus for every possible action. A GUI is a canvas, and there are established languages which creates frameworks of content which you should paint on this canvas. But this doesn't mean you speak one of this languages well or even at all.
Smart move by (for instance) Microsoft when they did that in Windows 95 and continued it til now. You could theoretically design the same functionality into a text user interface. Like if you type the name of something (a filename) and hit enter (or maybe tab? space? Whatever the designer comes up with) it could give you a menu to choose from context specific commands. It would seem pretty natural in that case if you are using post-fix (arguments(s) and then commands, like in Forth). Maybe something already exists like that.
How about:
$ file --help | grep util
-u, --utils output utilities related to FILE
$ file -u index.html
index.html: HTML document, ASCII text, with very long lines
cat index.html
ed index.html
lynx index.htmlindex.html <tab>
And you’d get open, copy, rename, create symlink, delete, compress, etc.
Why does the order of commands or their names have any influence on whether pipes can be used? How do you pipe the output of cp into awk?
I can try... Specifically, given a command that produces a list of "everything that can be done with the file", how do I cause the (unstructured) text of that list to be piped into a arbitrary other program, in the same way that `grep foo a.txt | bar` causes a list of occurences of 'foo' in a.txt to be piped into arbitrary program bar.
> How do you pipe the output of cp into awk?
$ cp -vT foo/ bar/* | awk '...'As I understood the suggestion re. file actions it is meant as some sort of interactive completion. So if I type the name of an image file and press tap, I am given the suggestions or options about resizing, format conversion etc. Several shells already have interactive completion of file names.
And I think that pattern makes sense from an exploration perspective. If you learn that file name + tab gives suggestions, then a lot of the learning about what the command line can do can be done directly in the command line.
And maybe it could be a command rather than a tab-press. Then it, given a file, prints typical actions/commands/tasks to stdout and then subsequent CLI tools can be used to process that output.
I really don’t see how this is incompatible with existing workflows :-)
Yeah, I was giving a example of a sensible way to design it, not documenting something that already exists; sorry if that wasn't clear.
> And maybe it could be a command [like `file -u FILE`] rather than a tab-press. Then it, given a file, prints typical actions/commands/tasks to stdout and then subsequent CLI tools can be used to process that output.
Pretty much that, yes.
> I also find it a bit hilarious that the example lists `ed` as the editor of choice.
I don't think unix had TECO as a standard utility, so I went with what was available.
index.html open | sed
(TUIs are, or can be, GUIs with box drawing characters instead of pixel displays. They're not necessarily any more scriptable or any less discoverable; however, a TUI on top of a command line, like Norton Commander or Midnight Commander, can be a real winner of a design paradigm.)
I think that some version of this dichotomy has existed at nearly every point of computer history where technology allowed it, and that is surprisingly far back!
"free space" doesn't turn it up, but on my system only turns up one result that obviously isn't it, no big loss.
"free" also doesn't turn it up, which seems like a missed opportunity. Going through the 40ish results before you're confident it's none of them is needlessly painful, but not crazy.
Both "disk" and "space" do turn it up, though, and also surface du (amongst about 50 other things).
I don't think scanning through <100 text items is clearly worse than digging through (say) the Windows control panel GUI.
~~~
I'd also note that TUI encompasses two kinds of thing - the utility in the shell (like df) and the captive interface that takes you away from your shell for an extended time as you navigate possible actions in some other manner. The latter has more of the benefits and drawbacks of a GUI.
~~~
In any case, I don't think your thesis is too far off, and I certainly welcome improvements to composability and discoverability across the board.
Everything? Almost certainly not! That is the main problem with GUIs. The "everything" is defined by the programmer, not the user. Sometimes that works for you, sometimes it doesn't.
It's important not to confuse TUI with "console". TUIs are essentially the same as GUIs in this discussion. CLI (console) is completely different. CLIs use a language to describe what you need. To use an analogy, imagine ordering food in a restaurant. You could get away with pointing at the menu as long as you're happy with getting the default configuration. If you want to ask for no cheese, or less mayonnaise, you have to use language.
No OOP language can have a search feature as useful as Hoogle:
https://hoogle.haskell.org/?hoogle=%5BMaybe+a%5D+-%3E+%5Ba%5...
No. One has to be trained to right-click. What about interfaces that don't have a right-click, such as a touch interface?
Not only that, but the right-click menu has to be programmed. A lot of designers want minimalistic interfaces and would remove anything that isn't used often. So your right-click menu won't have those features.
> TUI/console is very good for interoperability/automation/muscle memory, but doing one-off things is harder.
Are you kidding?! I've found that doing one-off things is massively easier and faster in a TUI than in a GUI!
> In comparison, I know that if I start going through GUI, eventually I'll eventually find the free disk space info.
I've found plenty of GUIs that simply don't have what I want. Or... maybe they do have what I want but I couldn't find it.
Are you suggesting that we switch to TUIs/CLIs on touch interfaces? If not, what's your solution?
> I've found that doing one-off things is massively easier and faster in a TUI than in a GUI!
For example?
My solution is that touch interfaces are a bad design in the first place. They're significantly less accessible to people with disabilities. They present a lot more problems with feedback about which buttons you're _about_ to press. And they're ficking obnoxious because everyone and their marketing team wants a completely different interface so nothing is ever consistent even on the "same" operating system.
> For example?
Example 1: download one file from a url mentioned somewhere
curl -fLsS "$(query for url)" -o ~/Downloads/file
Example 2: download a bunch of PDF files cat ./file | grep -P '\.pdf$' | while read -r url; do curl -fLsS "${url}" -o ~/Downloads/"$(basename "${url}")"; done
Example 2: move all PDFs that I just downloaded: mv ~/Downloads/*.pdf /path/to/pdfs
Example 3: find what text file(s) have some text grep -nRIiw "magic" /path/with/content
Example 4: find what pdf file(s) have some text find /path/to/pdfs -iname '*.pdf' -exec pdfgrep "magic" {} +
Example 5: compare filenames in the two sets: sort <(grep -lRIiw "magic" /path/with/content | while read -r path; do basename "${path}" .txt; done) <(pdfgrep -l "magic" /path/to/pdfs | while read -r path; do basename "${path}" .pdf; done) | uniq
And now, I have accepted a file from a team member which describes URLs to PDF reports with magic. I have generated a one-off report describing which files have magic content that needs to be reviewed because it contains magic that's described in in a local database.How about generating a git-diff, encrypting it, and emailing it?
cat <(echo Subject: diff for the work you needed) <(gpg -a -u inetknght -r recipient -o - -e <(git diff new..old)) | sendmail recipient
... Okay so those one-off things are complex things. How about simple things?Example 6: move a file.
mv ~/Downloads/foo ~/Documents/
Example 7: open a file xdg-open file
Example 8: delete a file rm file
Example 9: mount a thumb drive mount /dev/device /mnt/filesystem
Example 10: unmount a thumb drive umount /mnt/filesystem
Example 11: shutdown, and don't let any bad app stop the shutdown systemctl poweroff --force
All of these are IMO easier than in a GUIAnd that's just those who can speak English. If someone doesn't, it's just nonsense for them.
> One has to be trained to right-click.
One has to be trained to understand which commands exist and what do they do. I can't imagine someone without any training typing `grep -nRIiw`. Sure, you can look it up in the manual, but that's the thing - you shouldn't. You should consult the manual when you're using something for the first time or something isn't working. I can pick up any vacuum cleaner or get in a rental car and start operating them right away. I have to look up how flag works with different CLI apps. I shouldn't have to. Good design should be obvious.
That's why we're not typing `systemctl poweroff --force` to turn off a TV, we just press a button on a remote. And I can pick up remotes from other TV sets and turn them off without looking up their manuals.
> nothing is ever consistent even on the "same" operating system.
Funny you mention that. I tried some of your commands. Turns out, I don't have systemctl or pdfgrep installed. So much for consistency.
Don't get me wrong, I also hate touch interfaces, for all the reasons you mentioned. But saying they're "bad design" is not a solution – it's a starting point at best.
What alternative are you suggesting for smartphone-sized devices? Mobile phones did have physical buttons, but once touchscreen-only devices came out, customers voted with their money. So much so, in fact, that smartphones with a physical keyboard are a tiny niche today. That's because keyboards just don't work well with small devices. Using a CLI with a smartphone keyboard would be an awful experience.
TUI/console is very good for interoperability/automation/muscle memory, but doing one-off things is harder. If I don't remember the `df` command... what do I do apart from searching on the internet? Maybe searching man pages, but it isn't as fuzzy (e.g. `man -K "free space"` isn't very fruitful). In comparison, I know that if I start going through GUI, eventually I'll eventually find the free disk space info.
It's interesting that there is some analogy to object-oriented and functional paradigms -- if I have a rich object in a debugger in Python, I can call dir() on it to immediately see what I can do with it. Whereas if it's a simple dataclass, I'd need to search through code to find how I can use it. Might be a too far fetched analogy though.
I think we need all of it, and also need to make the distinction less apparent. Would be nice to make GUIs more composable, and TUIs more discoverable. Ideally it should be a spectrum of interfaces, so you don't have to make a hard choice and can gradually move into the direction you want.