New(ish) command line tools
jvns.ca
jvns.ca
tail -f /var/log/foo.log | fzf +s
Or something similar for output from a dev server: make serve | fzf --ansi +sEdit: Ah, I see. According to another comment you see the output of the file as it changes.
fzf will receive that input and in this case accumulate the new lines that have come in from tail -f. It will then stay around, present an interactive full screen text ui, and let you interactively filter the set of received lines based on substrings you enter at the fzf prompt. This while continuously incorporating new log lines coming from the pipe, from tail -f. The +s just says not to sort the lines, keeping the matches in the same order they appeared in the logs.
As for integrating with a “genders” host DB, there’s no direct support for it. But, lnav is scriptable, so I’m pretty sure it’s possible to write a script that does what you want. I can help with that if post in the github discussion: https://github.com/tstack/lnav/discussions
less +F -p pattern /path/to/log
(Ctrl-C to break out of tail mode. /pattern to interactively set search pattern.)I use this all the time, especially when I'm on a machine that I don't want to bother installing something like fzf on.
&pattern
Display only lines which match the pattern; lines which do not
match the pattern are not displayed. If pattern is empty (if
you type & immediately followed by ENTER), any filtering is
turned off, and all lines are displayed. While filtering is in
effect, an ampersand is displayed at the beginning of the
prompt, as a reminder that some lines in the file may be
hidden. Multiple & commands may be entered, in which case only
lines which match all of the patterns will be displayed.
Indeed, I thought it would behave like you describe.. when I was refreshing my memory of how the negative pattern filtering worked, I first did &/pattern and then &/^Npattern, and was surprised to see that it displayed zero matching lines.this is my version of less:
% less --version
less 581.2 (POSIX regular expressions)
Copyright (C) 1984-2021 Mark Nudelman[1]: https://github.com/gwsw/less/commit/6a070fc53799fb86e0fe3880...
- automatically have this for any command that outputs more than 10 lines?
- automatically exit when the main command (for example a dev server) exits?
- print the output of the main command to stdout after this is done?
https://gist.github.com/jpouellet/5278239
Mine blinks a little light if a command finishes after 30 seconds, and sends me an email if something takes over a minute.
Probably not. The output of a command typically goes directly to the terminal and does not pass through the shell, so the shell has no idea how many lines there are.
You could write a shell where that's not the case, but that would have issues with interactive things - what happens if you run e.g. vim or htop in that context?
You can pipe to `less -F` (`--quit-if-one-screen`), but note that the version of `less` shipped with macOS has a bug and might just swallow the output instead.
``` -F ........ --quit-if-one-screen Quit if entire file fits on first screen. ```
git branch | fzf | xargs git checkout
_ ._ _ , _ ._
(_ ' ( ` )_ .__)
( ( ( ) `) ) _)
(__ (_ (_ . _) _) ,__)
`~~`\ ' . /`~~`
; ;
/ \
_____________/_ __ \_____________ [alias]
fza = "!git ls-files -m -o --exclude-standard | fzf -m --print0 | xargs -0 git add"
Then if you run "git fza" you'll get a list of changed files in your repo, which you can use TAB to select/deselect. Hit enter and the selected files will be staged, ready for a commit. Extra cool is that it works from any subdirectory of your repo because it always lists files from the root of the repository. It's really useful for selectively adding lots of files from the command line.I then alias "ga" to "git fza" for even less typing :)
#.zshrc
alias -g F=" | fzf --multi"Main problem: you maybe don't do this kind of operation frequently enough to remember how it's called or how you aliased it.
$ ls / find # tweak until I have a list of things to rename
$ for file in $(ls / find...); do echo "mv $file $(echo $file | sed ... )"; done # this prints mv commands for renaming, I can inspect them as needed
$ for file in $(); do...; done | sh # execute the renaming
It is inspectable, easy to cancel (just don't pipe to shell), incremental... just needs wrangling with bash etc. which is a bit of a pain.It works for a bunch of other all-or-nothing commands, which are potentially quite destructive; use a for-loop to generate the commands, tweak until you're happy with it, then pipe to shell.
!ls
qaVypImv “escapeA” escapeJi”escapeA”escapejq99@aIf your problem can be solved by just regexps, there's a "rename" tool installed by Perl I've used for decades. E.g.
rename -n 's/JPEG$/jpg/' *JPEG
Will apply the substitution for JPEG at end of the filename to just jpg. The -n will run without renaming so you can see what it intends to do.What you have installed, and what Debian and its derivates ship is this: https://metacpan.org/pod/distribution/File-Rename/rename.PL
Most(?) other distros ship the one from util-linux: http://man7.org/linux/man-pages/man1/rename.1.html
ls | % {rename-item $_ -newname $('myfile_' + ($_.BaseName -replace '\D') + '.md' )}
No need to remember anything.Nope.
> to remeber
That's the point, you don't need to remember anything, it would come naturally after a day of tinkering with PS/pwsh.
You just write it for your current needs.
This example was just a quick one-liner, it's very simple:
ls | % { # get the file list, cycle for each item
rename-item # obvious usage: rename-item oldname newname
$_ # pretty obvious, the source - place the loop variable here ie file name
-newname # explicit calling for a parameter name, isn't really needed
$( # subroutine start or eval if you prefer, to construct the new file name:
# 'text' + (take property basename from the file and regex it) + 'text'
'myfile_' + ($_.BaseName -replace '\D') + '.md'
) # subroutine end
} # cycle end.
It could be simplified (in this example) to this: ls | % {
$a = 'myfile_' + ($_ -replace '\D') + '.md'
rename-item $_ $a
}
which could be even written as a one-liner if you prefer it right now, just add a semicolon after `$a = ...` ls | % {$a = 'myfile_' + ($_ -replace '\D') + '.md'; rename-item $_ $a }https://github.com/nmaggioni/wat
The tag system is especially useful to me when I know the general concept I'm after but don't remember the exact wording of the command.
In my app, you can rename using your favorite code editor, so you have access to all your keyboard shortcuts.
https://github.com/whyboris/Simplest-File-Renamer - MIT open source
I think folks should be aware of 'vimv' which opens your pwd in an editor and you just edit your filenames in 'vi' ... and all of the renaming happens upon saving and quitting.
Not sure if this is the official/canonical distribution, but for what it's worth:
> A more complicated example using numeric output to feed into the dialog(1)
> program for a full-screen progress display: ...
> Frequent use of this third form is not recommended as it may cause the programmer to overheat.
^- is that a wisecrack hidden in an otherwise serious man page?
This sentence was removed from the man page in pv 1.4.0, released in December 2012.
grep pattern1 **/* | grep pattern2 | grep -v exclude_these | grep -v also_exclude
The problem is this loses filenames and context lines in the output. I want to apply several positive and negative regexes, and only at the very end annotate with filenames and context. Anyone have a good workflow for this?Then I highly recommend: emacs / vim buffers
grep -inHv -e foo -e bar -e baz ps axjw | awk '(/zsh/ || /login/) && !(/awk/ || /direnv/)'
And you can easily add features like "print the first line unconditionally: ps axjw | awk 'NR == 1 {print} (/zsh/ || /login/) && !(/awk/ || /direnv/)'
IMO, awk is in a pretty uniquely sweet spot between grep and perl/ruby/python.Unfortunately I've not put in the effort to learn awk past printing the n-th column of ls (my typical use) - the extra syntax required to properly 'quote' and {} things puts me off.
rg --line-number --no-heading --color=always --smart-case "$@" | fzf -d ':' -n 2.. --ansi --no-sort --preview-window 'down:20%:+{2}' --preview 'bat --style=numbers --color=always --highlight-line {2} {1}'
I get a small preview of the file in the bottom 20% of my terminal, and I can use fzf's matching to further filter, or to exclude thingsI capture the output and then `cut` it up to get filename and line number, which then get used to open the file/line in vim
grep -P '(?=.*pattern1)(?=.*pattern2)(?!.*exclude_these)' **/*
Maybe not the most beautiful or easy to have at the fingertips, but could be worse.Previous discussion here: https://news.ycombinator.com/item?id=20455857
Also featured in that thread: https://github.com/akavel/up
For example: echo '' | fzf --print-query --preview 'grep -R {q} . 2> /dev/null'
https://gist.github.com/b0o/f0759c84af6ef773a37a499fdb1c05af
Example: you’re trying to find a file that contains the strings “MIT License” (case insensitive), “npm install”, and a match for “react-.*” somewhere in your home directory:
aag ~ ---- -i "mit license" --- "npm install" --- "react-.*"
The excessive dashes are necessary so that it’s possible to pass different options to each separate invocation of ag.In case it’s not clear why this is useful, normally ag (or grep) searches are linewise. It’s not so easy if you are looking for things that occur on different lines, and possibly in different orders.
perl -ne '( /foo/ and /bar/ and !/baz/ and !/splat/ ) and print "$ARGV: $_"' *
I didn't include the context part, since that would be more than a one-liner, but it's not hard to do in a short script.- Interactivity: the results are updated live as you type, so you catch typos sooner and can tweak the search terms as you go.
- The buffer of search results you collect with Embark is not dead text like it would be in the terminal, instead, each line is a link to the corresponding file taking you to the line that matched.
- Wgrep lets you edit all the matching lines in place!
Packages referenced:
1. Consult: https://github.com/minad/consult/
2. Orderless: https://github.com/oantolin/orderless
3. Embark: https://github.com/oantolin/embark
4. Wgrep: http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep....
function jqsk {
sk --tac --ansi --regex --query . --multi --interactive --cmd '{}' \
--bind 'enter:select-all+accept,ctrl-y:select-all+execute-silent(for line in {+}; do echo $line; done | pbcopy)+deselect-all' \
--cmd-history=${HOME}/.sk_history --cmd-history-size=100000 \
--no-clear-if-empty \
--cmd-query "cat $1 | jq --raw-output --color-output --exit-status '.'"
}
I should look into whether fzf or any of the other tools in this thread can be coerced into doing the same thing, the above is pretty verbose and arcane, and it doesn't always behave the way I expect. -H File name
-R Recursive (directories)
-n Line number awk '/pattern1/ && /pattern2/ && !/exclude1|exclude2/ {print FILENAME, $0}' */*[1] https://github.com/flurie/AdventOfCode/blob/main/2021/jq/d14... - unfortunately, this is the point at which I realized the stdlib was a little too anemic for general purpose solving and gave up
Is anyone aware of any other comparable shell tool for tailing a set of logs?
You can find the last failure I submitted here[0].
[0] = https://groups.google.com/g/lnav/c/C2uORuyKmy8/m/5Knove9gBQA...
[1] https://hurl.dev
« new inventions
Here are some tools that are not exactly replacements for standard tools:»
Which isn't to say that it wasn't neat to learn that top can do that, but I'm probably still going to continue using htop.
[1] https://github.com/dandavison/delta
(edit: nevermind, somehow I missed it)
Straight from the repo: "Like jq, but for HTML."
I find it useful for quickly hacking scripts together and exploring data. Very useful for the iterative process of finding good CSS selectors with the data that I can get without javascript running.
--- [1] https://github.com/mgdm/htmlq
For example, something I usually do is:
curl --include --location https://example.com | tee /tmp/example-com.html | htmlq --base https://example.com a --attribute href --remove-nodes 'a[href*="#"],a[href^="javascript"],a[href*="?"]'
This grabs the page, shunts a copy to /tmp for subsequent, iterative testing, then tries to grab all the links while filtering out any links that have a '#', '?', or start with the word 'javascript'. This is super helpful when I'm just exploring some HTML scrape and trying to build a graph of links without having to pop out a proper programming language just yet.How many times have you wanted to dedup a (text) file, but definitely didn't have enough memory to perform the task? I found this one day when I had to dedup a set of .ndjson.gz files which totaled a cumulative 312 GBs. Utilizing the bloomfilter option, I was able to dedup the records without any large investment on my part.
Anyways, runiq[1], "[an] efficient way to filter duplicate lines from input, à la uniq".
It provides several ways to filter of which I almost always default to utilizing the bloomfilter implementation (`-f bloom`).
---
sed (ed) - 1979 (1971)
I was an 'ls' purist before, I've tried various CLI file managers in the past and they all felt like they added too much friction, with the one exception of nnn which I briefly used before finding broot, which just feels really fluid and natural.
I suggest everyone to have at least a short glance at the introduction at https://dystroy.org/broot/
Bash doesn't really have any of this, so if you're a bash user you're out of luck. Don't know about fish.
# fs 'foo' will find files/dirs with 'foo' anywhere in the name irrespective of case
fs() { find -iname '*'"$1"'*' ; }> https://github.com/visit1985/mdp
I use pandoc to convert markdown to powerpoint decks, it's a great workflow as you can preview and tweak the content and then apply the firm theme before the presentation.
pandoc -f markdown input.md -o output.pptx
>have it auto-switch kubernetes context by location
Now I'm sold, thanks!
git config --local core.hooksPath $PWD/.githooks
export DOCKER_CONFIG=$(realpath secrets/docker)
Combine that with git-crypt[0] (obviously, don't commit secrets in plaintext to your repo!) for example and you have some really nice ergonomics.Not enough people know about direnv.
Also, many scripts start by just defining a bunch of variables -- and many of those, in terms of other variables. Say, a PROJECT_ROOT directory, and a PROJECT_DOCS directory defined relative to that, etc. Then, a bunch of command parsing logic, after defining all those default values, so the user can set values of their own. Then, finally, the script can start doing the thing it was put there for in the first place.
With the .envrc approach, some of that stuff is pulled out of the script (making it shorter and simpler) and considered part of the directory environment.
[1] https://12factor.net/configExample server pattern to default to production:
if "PROJECT_IS_DEBUG" in os.environ:
DEBUG = True
ALLOWED_HOSTS = ["*"]
else:
# production configuration by default
All for a one-time configuration setup. A further boon of this workflow is that systemd natively supports an EnvironmentFile configuration, so you can re-use the same configuration format from development to production.Projects I'm on also tend to wind up with an etc/ directory that configures things like PATH and tab completions for a good baseline experience - think of it as standardizing and isolating the snippets many projects tell you to put in your ~/.bashrc to work on the project.
Direnv makes it easy to automatically load those, too.
It really did revolutionize the way I work, by making it trivial to make projects much more self-contained, the way I'd always wanted them to be but hadn't been quite sure how to achieve.
I've only used Nix for managing my personal installed package on OS X so far, but I believe direnv works really well in tandem with Nix - use a Nix file to define your project's dependencies and use direnv to automatically activate all those dependencies whenever you're in the project's directory.
It makes it a breeze to pull in a commit and set up a development harness that pokes at whatever thing I need to poke at in my local environment. And it does it without changing a line of code or command line invocation, which is a big deal in polyglot environments with various build constraints (not passing -DFLAG=thing is enormous in a big C/C++ code base, for example).
Even just being able to point whether a service is looking at a dev/production/local service/database is a big deal if you've invested in IaC and don't want to mess with any config files to do your work (as .envrc is probably in your .gitignore).
Kind of imagine if git didn't change repo when you switched directory, that was how it felt.
Troubleshooting system issues can also be done with SystemTap[1], which looks cool, but I haven't personally tried it yet.
[0]: A cool example of using them is https://www.brendangregg.com/blog/2021-08-27/slack-crashes-s....
> Miller is a command-line tool for querying, shaping, and reformatting data files in various formats including CSV, TSV, JSON, and JSON Lines.
Both visidata and miller are essential tools to process/view CSV/TSV files, way better than LibreOffice or Excel in terms of performance on large files.
After a few years without an active maintainer, as of a few months ago we now have a group working slowly but actively towards a Mosh 1.4 release. I think the main benefit people are expecting will be support for 24bit color escape sequences, but I'm also hoping we can get some fuzz targets, etc.
The authors consider it feature complete hence the lack of updates.
For me it's the best complement for a command line focused git usage, because it offers a far better (but still streamlined) experience for staging chunks than "git add -i", through its "tig status" TUI interface.
One thing that I never bothered to research if it can be modified and the defaults bother me a little is that it does not use vim keybindings (gf for loading a commit, for example).
- Diffing YAML files: https://github.com/homeport/dyff
- Inspecting Docker image layers: https://github.com/wagoodman/dive
- Interactive HTTPS proxy: https://mitmproxy.org/
Been meaning to try out xplr[1] which I came across the other day.
Ask HN: Best Command-Line Applications? https://news.ycombinator.com/item?id=18483460
Command line tools for productive programmers https://news.ycombinator.com/item?id=27992073
An Illustrated Guide to Useful Command Line Tools https://news.ycombinator.com/item?id=21363121
1. You need to be careful to avoid "works on my machine" moments
2. You need to remember that you did it in case you need to undo it.
One (very) minor issue I have with it is that when the file is very small - a couple words or lines at most - then the "decorations" it prints around the content get distracting and make the content slightly harder to read. Maybe I should just write a wrapper around it that does a `wc` first and decides whether to do a `bat` or a `cat`.
I would love a meta tool that, every time I use one of the old tools, it automatically gives me a notice to use the new one instead, so I can learn. Then again I guess I could alias the old ones to point to the one one.
# search by content:
$ mdfind some_string
# search by name:
$ mdfind -name my_file.txt
Both commands return a list of files matching the query. [[ $OSTYPE =~ ^darwin.* ]] && export FZF_CTRL_T_COMMAND="mdfind -onlyin . -name ."
When you hit ctrl+t, you'll get mdfind's output for all files in the current working directory and below, auto-piped into fzf for fuzzy matching. You can do something like type "vim " then hit ctrl+t, find the file, hit enter twice to start editing it. I wrote a quick guide on installing fzf/fd/ripgrep with powerlevel10k/oh-my-zsh/zplug on MacOS, because I would get asked how to replicate my setup: https://gist.github.com/aclarknexient/0ffcb98aa262c585c49d4b...It's like a bookmark manager for commands.
Also good for sharing them with the rest of your team, via a git repo.
I write quick and dirty single-purpose utilities for myself because I want relatively simple programs. I try to keep program size reasonably small so I use C not Go or Rust. I avoid creating options. FWIW, seems like that was true of most of djb's utilties, too. Some of the best "new" UNIX utilities I have seen have come from from people who use djb's C functions and/or copy his programming style, including the preference for small program size and few-to-no options. For example, the authors of runit or s6 have some interesting utilities. The author of tinysshd has some useful ones as well. These projects are generally not popular but they are generally high quality, IMHO.
There are some JSON utilities listed on this blog page. Despite so many options for libraries and programs to process JSON, I still cannot find one that does something very simple: 1. extract JSON from HTML, 2. print it in a customised, human-readable, left-justified format that 3. makes it easy to process further with other programs. Hence I wrote a stupid program for myself that extracts JSON, prints the keys and values left-justified, making it easy for me to read with less(1) and to process with traditional UNIX text-processing utilities. (I am probably mistaken but I believe the one I wrote may be able to operate at the same speed regardless of the size of the JSON data. This needs to be tested.)
I have written several shell scripts over the years that have a subset of the functionality of fzf (or a superset of urlview's, which came much earlier), namely finding and selecting items from lists. I am still not a fzf convert because generally it does not do anything essential I cannot already do myself. Plus it is larger, more complex and generally slower.
Someone once said the best interface is no interface. For me, the less required user-interaction (including selecting options), the more powerful the utility.
Was this from an article by Golden Krishna, later turned into a book by the same title?
Archived article (or, how to open your car door in 13 steps): https://web.archive.org/web/20120831083217/http://www.cooper...
Previous HN discussions:
https://news.ycombinator.com/item?id=4616945 (2012, 87 comments)
https://news.ycombinator.com/item?id=4454004 (2012, 34 comments)
https://news.ycombinator.com/item?id=4959406 (2012, 91 comments)
https://news.ycombinator.com/item?id=9218686 (2015, 56 comments, about the book)
EDIT:
One of the old comments also addressed Unix tools more directly, referring to djb's work:
https://news.ycombinator.com/item?id=4456795
What are some relevant writings by djb on user interfaces?
Maybe no one besides me ever actually said those exact words with respect to command line programs. What did happen is someone wrote that he found user interfaces on command line programs are not "good" interfaces. He then suggested that writing command line programs that did not have to parse options could be a "security" tactic when programming. See "5. Don't parse" in the text file below.
tnftp -4o"|tar xOz qmail-1.03/SECURITY|less" https://cr.yp.to/software/qmail-1.03.tar.gzThe real reason people are hesitant to use new tools is that there is a massive switching cost for most of them.
Great example is working with Unix streams instead of objects as in powershell.
At least one of them (fd) was designed specifically to be simpler to use than its UNIX counterpart (find). And others though as simple to use (ripgrep, scc) they're much more performant than the tools they replace (ack, cloc).
I got tired of piping head into tail and found it simpler.
Examples:
line file.txt 5 to 9
cat file.txt | line —column 4 to 20
I thought “line” was very Unix sounding and kinda cute, but like a lot of these projects would never make its way into the gnu utils so I thought what’s the point. That and of course to a beginner Awk user, those kind of operations are child’s play. I thought about csv and printing lines between matching words, but it’s all about KISS.
The main challenge to doing this well is having good taste and experience. It may be that if you really tried to do this, you'd face tons of UX challenges, and you'd find that tools like awk really were in the sweet spot already.
Even something simple as "cmd | awk {print $1}" in awk is something like:
import sys, re
for line in sys.stdin.read().split('\n'):
s = re.split('\s+')
if len(s) > 0:
print(s[0])
else:
print()
And I probably got that incorrect as it's probably not the way to read stdin (it's been a while since I programmed Python).I can list many gripes with Unix tools, but "awk bad" isn't on that list. It's a small language that solves a very specific problem, and does that surprisingly well. The syntax is about as simple as it gets – no idea how it's "terrible" or "impossible to remember", and it's certainly not "insane" as you seem to be suggesting.
It sounds like your "line" replicates a use of sed that I use all the time, printing a contiguous range of lines.
The example:
line file.txt 5 to 9
can be:
sed -n '5,9p' file.txt
You mention using awk, which totally works, but to me is much less ergonomic.
You don't explain what line's "--column" option does so I'm not sure what the equivalent of that might be. That might be where awk comes into its own ... :)
> [...] and printing lines between matching words
This is the same sed command as above, but using regular expressions for the address part:
sed -n '/^func doit/,/^}$/'
will print just the function called "doit" (in properly formatted go).
Could you (I mean "one") design a "friendlier" (or more "beginner friendly") user interface than sed presents? Yes, obviously (you did exactly that). But unlocking the power (or even just beginning to "unlock" the power) of the standard tools (sed, awk, grep, tr, cut, paste, find, xargs, ...) can get you a really long way. Of course, the initial problem is how to know that one of those tools can solve the problem you have in your head.
("Bonus" sed content: replace "head":
Instead of
head -n 5
do
sed 5q
To replace tail you need tac (or "tail -r", haha))
It was simply the equivalent of Awk printing columns like this.
awk '{ print $2, $3, $4 }'
Except with support for column ranges, which I don't think Awk supports without writing a for loop.
Something convoluted like :
awk -v start=1 -v end=3 '{ for (i=start; i<=end;i++) printf("%s%s", $i,(i==end) ? "\n" : OFS) }' marks.txt
Idk, the amount of Unix that GNU and BSD accepted as a bare environment, the range is single purpose programs like tail and mini interpreters which are powerful but require a lot of skill. If I worked in system administration, and I HAD to use shell, I'd hold onto Awk for dear life. But I don't, so it's sort of this ancient swiss army knife.
Select what tooling you want, it will be installed using your package manager
[ ] delta
[ ] bat
...
pacman -Syu git-delta bat ripgrep fd
Saved you a weekend ;)asdf is another good option with most of them.
https://github.com/peteryates/dotfiles/blob/master/Makefile#...
https://github.com/tobert/pcstat https://hoytech.com/vmtouch/
tail -f /var/log/nginx/access.log | cut -d' ' -f1 | logtop
as a live updating replacement for a |sort|uniq -c|sort -gr|headNo affiliation... just happy user relieved at deleting Postman :)
You still have to create the collections in Postman, however.
---
[1] https://news.ycombinator.com/item?id=31009609
[2] https://hurl.dev
> The mosh client logs in to the server via SSH
This is a cool list overall though.
Curiously most of those tools implement things Emacs have since decades. Obligatory #define NOFLAME, I was and to a certain extent a unix guy but after having jumped the ship to Emacs I start seeing in practice many aspects of unix inferiority respect of classic systems, far beyond the Unix Haters Handbook.
File renaming? Dired do that and more than many modern tools, not only in mere editing (wdired-mode) but also in selecting what to edit (marking via regexp, narrowing, manually select files "killing" others etc) in a far more flexible than an unix CLI tool piped to an editor, results are the same of course, easiness it's at another level.
Narrowing/Fuzzy searching? Similarly from Helm to Counsel passing through consult, ido, ...
#endif // NOFLAME
Anyway I still use CLI daily simply because much inhabited to it and for certain things it's quick, and I use some of those tools but the interesting part is not much the tool (dangerously aliased sometimes to overwrite original ones because who remember their name?) but the trend: in the last decade I see a kind of resurgent interest in unix and FLOSS, many that in the past have said "ah, yes, nix are powerful but I need to work no time to learn, ..." in the last decades have started much using GNU/Linux even inside Windows and more and more are accustomed to nix model. Emacs itself seems to have seen a sort of resurgent popularity and that's make me think: did we need so much time to learn?
I mean, we have had the IT revolution from Xerox. Just very few have understood its power and the GAFAM born out of it, starting from the first modern IBM in term of using and ruining Xerox PARC tech to size it's power still giving something to end users. The unix revolution succeed but again for most is a thing of the past and it's successful model is it's failure: they started saying that Xerox desktop model is just too complex and expensive people needs cheap and simpler things, the public agree unix succeed, in just few years they start realizing that no, good iron is needed, GUIs are needed etc and again the big iron era succeed but for a small period of time. PC era wipe it with again cheaper and crappy-er things. PC era succeed and in a moderately short period of time rediscovering of the past desktop model (without knowing it for most) happen, for instance the trend from widgets-based GUIs to document-based ones, the trend toward text-centric works and the recent interest in classic unix witch is actually the most common living vestige of classic model: not really end-user programming, that's Emacs, but at least composability via IPCs in CLI, from IDEs to editors, from DE to WM, perhaps tiling's ones, for some from unix model to Emacs.
Long story short I see a trend that "knowledgeable" people veeeery slowly rediscover classic tech, if that's really a trend and we (society) really need such timeframe to learn... Well... It's a bit sad...
What do you think?
Resurgence? Google tells me otherwise... https://imgur.com/a/urcePZq