I really enjoy using a command-line interface instead of a graphical user interface, and was wondering if anyone had any solid recommendations for applications that one can use in a terminal window.
I agree. A lot of them come with a UNIX system, although there are others. I use some of the moreutils stuff. For email, I use Heirloom-mailx. For text editing, I use vim. For database I use SQLite. For typesetting I use TeX. For processing pictures I implemented my own package called Farbfeld Utilities. For making MOD/XM musics, I wrote AmigaMML which uses a text file rather than the GUI that many other programs do. Hopefully other people on here can mention even more, because I am interested in the answer too, and probably my answer is insufficient to the original asker anyways.
Maybe the best part of bash for me is AWK - so useful, and enjoyable to use. I use ffmpeg a lot for making movies from images, video conversion etc. I use Sage on the command line, mostly for programming in Cython and mathematical stuff with the Sage/Python REPL. It was 2.7GB (!) and comes with an absurd number of libraries and packages[0], mostly for maths and graphics. I started by using it in a browser notebook, but switched to the command line and never went back.
It's really worth the time to learn. It's pre-installed basically everywhere, it's amazingly useful. It has the features of a modern text editor all in a command line.
Tail -f works by opening the file and remembering the byte offset, if it’s a log file that gets flushed/wiped then tail -f won’t see anything until the logs fill enough to exceed the previous file contents.
Unless you pass the option --follow=name in which case tail will if necessary reopen the file and follow it even when log-application has closed and moved it elsewhere and opened a new one of the same name.
If you need to handle XML, xmlstarlet (http://xmlstar.sourceforge.net) is fantastic, and much more powerful than the standard line-oriented tools like sed and awk for this task.
The only issue I have with xmlstarlet is that it can be sort of a pain when there are xml namespaces in the document. Most of the time, you just have to pass it the long option that ignores them all together
I'm not big on applications, period. Activities should be decomposed (or at least decomposable) into individual actions that I can stitch together in the shell.
I agree, we can use the pipes to put them together. That is how I do such thing, and design these programs, at least.
For example, one program is "playmod" which read a module music file from stdin, and write the raw audio data to stdout. The program "amigamml" is takes the MML code from stdin and write the module music file to stdout. And then, program "aplay" is playing the audio data from stdin on the speaker. Other example can be, "ls" to list files, "shuf" to put into a random order, and "xargs" to run another program for each one, and a shell script might then do "playmod" and "aplay", you can play the music at random!
There's a frequent (but by no means universal) distinction drawn between "applications" and "utilities". In the former case, you have repeated interaction with a single process, typically with some measure of "ownership" of its display port. On the other hand, a utility typically does a single thing, produces some output, and then exits.
For working on servers, tmux + mosh is a killer combination: mosh makes your connection resilient to network issues and tmux gives you (back) scrollback and cross-session persistence.
mutt is hard to beat as an email client and circe (an emacs package) + znc on a digital ocean instance or equivalent makes for a great persistent irc session.
I am a convert from Spacemacs to Doom, and I have found that one of the main differences that sets Doom apart is easier configurability than Spacemacs. In Doom, there is still the concept of "layers," but IMO it is much easier to figure out what the layers are doing and customize them from there.
Also, I have found Doom to be much quicker (takes about 2 seconds to load, not using server/client) and less buggy than Spacemacs. I would highly recommend giving Doom a try!
This. Also, the developer is responsive on his Discord server should you have any issues with the editor. Henrik is patient, kind and reliable, rare traits for open source projects these days.
I use git so much that I made these aliases in zsh:
alias g="git show"
alias gh="git show HEAD"
alias gs="git status"
alias gl="git log"
alias gco="git checkout"
alias gd="git diff"
alias gbl="git branch -v"
alias gbd="git branch -D"
alias gri="git rebase --interactive"
alias grc="git rebase --continue"
alias gra="git rebase --abort"
alias gst="git stash"
alias gsta="git stash apply"
alias gx="gco -- \*; git reset HEAD \*"
alias gcp="git cherry-pick"
alias gcpc="git cherry-pick --continue"
alias gcpa="git cherry-pick --abort"
A few hundred instances of "gs" in my .zhistory :)
alias ..="cd .."
alias ..2="cd ../.."
# ... you get the idea, mine goes up to 5
function mkcd () { mkdir -p "$@" && eval cd "\"\$$#\""; }
alias h="history|grep"
hahah I have gs and gb(branch), just because I'm just constantly typing them(sometimes for no reason at all), others I end up typing the full commands tho
I’ve been using short aliases for my most frequently used git commands for a few years now. I can’t imagine not using aliases.
alias st='git status'
alias dp='git diff'
alias di='git diff --cached'
alias aa='git add -A'
alias cm='git commit -m'
alias pu='git push'
Having these aliases of mine makes these actions something that you don’t need to spend any mental effort to perform at all.
I highly recommend others to define aliases that make sense to them for the most used got commands.
Mine are named the way they are because the two letter alias represents how I think of the action that the command performs:
* st - status
* dp - diff pending
* di - diff
* aa - add all
* cm - commit
If you define your aliases this way (speaking to the other readers of this thread, not the person I am replying to), you will find that the combinations become muscle memory quickly.
Notice also that unlike a lot of other people including the person I am replying to, my aliases are not prefixed with “g”. Again this boils down to your personal way of thinking. I’ve used other version control systems before, switched to git several years ago, and use git pretty much exclusively. I am of course aware at all times that I am working with git, but at the same time when I think of actions to perform, I don’t think of them as “git this or that”, I only think of the “this or that” part. If that makes sense :P
But yeah, find aliases that work and make sense for you.
SCM Breeze has aliases like that, plus a bunch of other convenient things like numbered shortcuts for branches and files: https://github.com/scmbreeze/scm_breeze
Since git is by far the command a lot of people type the most, this shell comes in really handy. It supports all regular git aliases, has autocompletion, and you can set default commands to be run when you just press return. It's amazing how much typing it saves.
If you aren't using tmux or screen, you probably should be, especially over SSH sessions. They allow you to have multiple consoles open and switch between them, split window, and disconnect from SSH and then reconnect with all your things still open and running (as long as the server stayed running).
I use some scripts around screen (and tmux would do the job at least as well, just haven't had reason enough to switch) to manage contexts for my shells. The key is that that process will be the parent of any shells I spawn in contained windows, and so if I set an environment variable (I use SESSION) before kicking off screen it will be inherited, and visible in my bashrc. This lets me set up a lot of context specific things - path and functions and aliases - but the single best thing about it is a separate bash history per context.
I have a EC2 instance who's main purpose is to run a screen session. I ssh to my EC2, and load that screen. I have every server I manage in it's own "window" inside this screen. I run screen on each of these machines, so I can hop between inner and outer screens.
As someone who hasn't invested much time into tmux/screen, what are the benefits of it over just using eg; multiple terminal tabsn or using the terminal's built in split windowing? I'm sure there's probably a benefit but I dunno what it is
It persists your session, so if you get disconnected you can just log in again and 'tmux attach' to resume from where you left off. Any long running commands will still be running.
Both tmux and screen allow you to attach/detach. Thus you can log off, and you can pick up your session later.
For example, yesterday I logged into a Linux server at DigitalOcean via SSH. I ran tmux, started a long-running job, detached the session. I closed my laptop to go home for lunch. When I returned at my desk, I logged into the server and reattached the tmux session so I could see the results.
If it's all on one device and no networking, I don't know of any great benefit. But if you sometimes connect to the machine remotely then Tmux allows you to pick up an existing session, e.g.
You open tmux on your desktop, open some command line things, then walk away and pull out your laptop or desktop, SSH to your computer, "tmux attach" and have the same session open - and it's open on both devices, both seeing the same updates at the same time, like a terminal-vnc.
I agree with everyone else that it's great on remote systems, but the reason I use it locally too is because I can set up all a project's "tabs" with just one command. I have dozen-line scripts for each client/project that will either create or attach to a tmux session, and when creating set up all the windows how I want: setting their names, cd'ing, opening psql, tailing a log, changing the bottom color (green for development, yellow for staging, red for production), etc. For Rails work I typically have separate windows for models, controllers, views, stylesheets, and javascripts. It makes it really easy to get started after a reboot, or just hide projects for a while and bring them back quickly.
occasionally i need to restart the GUI. using tmux locally is very helpful for that. also sometimes i log into my workstation from remote, like when i am travelling. it's nice to be able to access the running session.
One useful reason to use it over a terminal is portability. If you're happy mostly working in the terminal then tmux will be the same on every OS your work on even if your favourite terminal isn't available.
rsync. It’s installed everywhere and makes it super easy to keep source code in sync between laptop and remote servers. It’s so fast that I completely ignore more advanced solutions based on fanotify or similar, and literally include rsync before every “build/run” command during development.
I used to use ag (the silver searcher) [1] before, and `ag` was practically a muscle memory to me, but then I came across ripgrep and it was so much faster. I've now installed a static binary of ripgrep in every machine I have SSH access to.
* fzf - a general-purpose "selector" ui for choosing "things" from a list based off, such as your history (bound to ctrl+r) or files in a directory (bound to ctrl+p with input generated by bfs or fd)
* ffmpeg - except I am much more likely to use it via one of the wrapper fish scripts I've written such as ffencode, fftrim, ffconcat, ffmute, etc. because it is (necessarily) so damn verbose and infinitely tunable.
* tmux - if I'm working remotely or on a headless machine where I can't just ctrl+shift+n to open a new terminal window (which I prefer)
grep is usable on very large code bases, because after the first scan, all the sources are loaded in the file system cache, so the successive grep are done in RAM and are very fast.
So much so that I almost never use ctags despite the improved semantic search (you can find more easily the exact identifiers and distinguish them by category). grep is just as fast and precise enough.
Grep might be fine 99% of the time, but there's no reason to not drop a ripgrep binary on every machine I use regularly.
Ripgrep is faster across the board and has better defaults for working in Git repositories. Since I'm working with a large codebase managed in Git, it's a no-brainer.
If I had to pick a single utility, it would be pv[0]. It's very simple, but I find myself using it all the time. Basically you stick it in a pipeline of commands to get a progress bar. The simplest usage is just to replace cat or input redirection with a call to pv. Saves a lot of time when I can quickly find out if the command I wrote is going to take 30 seconds or 30 minutes.
392 comments
[ 2.8 ms ] story [ 280 ms ] thread- Pandoc a handy document format converter: https://pandoc.org/ - Ripgrep, a faster grep: https://github.com/BurntSushi/ripgrep - There are quite a few prompt-toolkit based CLI which have been really nice: * mycli (https://github.com/dbcli/mycli), pgcli (https://github.com/dbcli/pgcli) * ptpython/ptipython (https://github.com/prompt-toolkit/ptpython) - Youtube-dl: http://rg3.github.io/youtube-dl/ - fzf a fuzzy finder for the console: https://github.com/junegunn/fzf - jq for JSON manipulation: https://stedolan.github.io/jq/ - Miller for CSV/TSV: https://github.com/johnkerl/miller
I would imagine you have already scoured the "awesome" lists: https://github.com/agarrharr/awesome-cli-apps#terminal-utili...
[0] http://www.sagemath.org/links-components.html
It's really worth the time to learn. It's pre-installed basically everywhere, it's amazingly useful. It has the features of a modern text editor all in a command line.
I've taken this list to be of thing things that run in a terminal rather than strictly non-interactive programs.
Works on BSD `tail` too. :)
A Python version of the Linux watch command:
https://jugad2.blogspot.com/2018/05/a-python-version-of-linu...
Similarly jq (https://stedolan.github.io/jq/) for JSON data is great.
For example, one program is "playmod" which read a module music file from stdin, and write the raw audio data to stdout. The program "amigamml" is takes the MML code from stdin and write the module music file to stdout. And then, program "aplay" is playing the audio data from stdin on the speaker. Other example can be, "ls" to list files, "shuf" to put into a random order, and "xargs" to run another program for each one, and a shell script might then do "playmod" and "aplay", you can play the music at random!
mutt is hard to beat as an email client and circe (an emacs package) + znc on a digital ocean instance or equivalent makes for a great persistent irc session.
File browser https://github.com/ranger/ranger
Emacs - It does anything you want.
Emacs If you like vim keys bindings - http://spacemacs.org
Terminal multiplexer - Tmux
Also, I have found Doom to be much quicker (takes about 2 seconds to load, not using server/client) and less buggy than Spacemacs. I would highly recommend giving Doom a try!
Here are my top commands by frequency of use:
total is of ~16k history lines... this means one in ever 4 commands I type is git! Wow I didn't know that. Probably `git status`...Aliases in my ~/.gitconfig:
No need to install oh-my-zsh you can just take the file or cherry pick (!) the useful ones.
I may drop oh-my-zsh completely and just set up zsh with the small subset of plugins I use.
[1] https://github.com/robbyrussell/oh-my-zsh/tree/master/plugin...
I highly recommend others to define aliases that make sense to them for the most used got commands.
Mine are named the way they are because the two letter alias represents how I think of the action that the command performs:
* st - status
* dp - diff pending
* di - diff
* aa - add all
* cm - commit
If you define your aliases this way (speaking to the other readers of this thread, not the person I am replying to), you will find that the combinations become muscle memory quickly.
Notice also that unlike a lot of other people including the person I am replying to, my aliases are not prefixed with “g”. Again this boils down to your personal way of thinking. I’ve used other version control systems before, switched to git several years ago, and use git pretty much exclusively. I am of course aware at all times that I am working with git, but at the same time when I think of actions to perform, I don’t think of them as “git this or that”, I only think of the “this or that” part. If that makes sense :P
But yeah, find aliases that work and make sense for you.
Since git is by far the command a lot of people type the most, this shell comes in really handy. It supports all regular git aliases, has autocompletion, and you can set default commands to be run when you just press return. It's amazing how much typing it saves.
Gron (grep JSON) is handy when you get a massive API response and quickly need to figure out what subkeys interest you.
The silver searcher (ag) is my go-to code search tool. I'll have to try ripgrep to compare.
Pass is neat for injecting personal secrets into bash scripts securely.
https://beyondgrep.com/feature-comparison/
The main screen instance is started with:
screen -S outer_screen
I then create a screen session for that EC2 with
screen -S inner_screen
I pop open new screens with this handy command:
screen -S outer_screen -X screen -t newmachine ssh user@newserver.example.com
For example, yesterday I logged into a Linux server at DigitalOcean via SSH. I ran tmux, started a long-running job, detached the session. I closed my laptop to go home for lunch. When I returned at my desk, I logged into the server and reattached the tmux session so I could see the results.
You open tmux on your desktop, open some command line things, then walk away and pull out your laptop or desktop, SSH to your computer, "tmux attach" and have the same session open - and it's open on both devices, both seeing the same updates at the same time, like a terminal-vnc.
And you can variously use them to allow two separate users to share the same session, either one controlling and others read-only, or multiple-editing ( https://unix.stackexchange.com/questions/2523/what-are-other... )
I used to use ag (the silver searcher) [1] before, and `ag` was practically a muscle memory to me, but then I came across ripgrep and it was so much faster. I've now installed a static binary of ripgrep in every machine I have SSH access to.
[1] https://github.com/ggreer/the_silver_searcher
https://beyondgrep.com/feature-comparison/
https://github.com/beyondgrep/website/issues
* autojump (aka j) - for changing directories quickly
* open - required to interact with the non-cli world, ships by default on macOS and here's one for Windows/WSL: https://github.com/neosmart/open
* imgpaste - for pasting screenshots into a PNG or JPEG directly (https://github.com/neosmart/imgpaste)
* pbpaste - for pasting into the shell (or if you're on Linux or Windows: https://github.com/mqudsi/fish-config/blob/master/functions/...)
* fzf - a general-purpose "selector" ui for choosing "things" from a list based off, such as your history (bound to ctrl+r) or files in a directory (bound to ctrl+p with input generated by bfs or fd)
* neovim - my configuration here: https://github.com/mqudsi/nvim-config
* ripgrep - for finding strings in files
* fd - for finding files quickly
* sed (with -r) - insanely powerful for common string operations
* tr - lets you deal with line endings, which sed can't
* youtube-dl - download youtube videos from the CLI
* curl/httpie - (scriptable) network requests
* aria2c - high-speed (multi-threaded) downloads and torrent downloads, it just works
* jq - for manipulating json in shell scripts
* ncdu - find space taken up by directories/files, but it's aging and in need of a dire rewrite like fd/rg did for find/grep
* pbedit - edit the contents of the clipboard in your favorite editor https://github.com/mqudsi/fish-config/blob/master/functions/...
* weechat - irc in your command line
* ffmpeg - except I am much more likely to use it via one of the wrapper fish scripts I've written such as ffencode, fftrim, ffconcat, ffmute, etc. because it is (necessarily) so damn verbose and infinitely tunable.
* tmux - if I'm working remotely or on a headless machine where I can't just ctrl+shift+n to open a new terminal window (which I prefer)
I'm not sure what you mean by "deal with line endings", but sed can operate across multiple lines.
https://www.gnu.org/software/sed/manual/html_node/Text-searc...
https://www.tecmint.com/fzf-fuzzy-file-search-from-linux-ter...
----
I use the Silver Searcher all the time. Very fast.
https://github.com/ggreer/the_silver_searcher
----
tig, a text mode interface for git.
https://github.com/jonas/tig
https://github.com/BurntSushi/ripgrep
grep is usable on very large code bases, because after the first scan, all the sources are loaded in the file system cache, so the successive grep are done in RAM and are very fast.
So much so that I almost never use ctags despite the improved semantic search (you can find more easily the exact identifiers and distinguish them by category). grep is just as fast and precise enough.
Grep might be fine 99% of the time, but there's no reason to not drop a ripgrep binary on every machine I use regularly.
Ripgrep is faster across the board and has better defaults for working in Git repositories. Since I'm working with a large codebase managed in Git, it's a no-brainer.
* htop - better version of top for multi-core machines
* tmux - when you want to run long-running commands
https://www.ivarch.com/programs/pv.shtml