11 ms·
Shell Productivity Tips and Tricks
- andreareina 7y agoProcess substitution deserves a mention: http://www.tldp.org/LDP/abs/html/process-sub.html http://www.tldp.org/LDP/abs/html/process-sub.html
- tcoff91 7y agofzf fizzy history search with ctrl-r is my favorite new shell trick. Fzf is a wonderful program
- gimboland 7y agofzf's great. I use it for a quick/easy git branch menu, complete with preview of recent history of each branch: https://pastebin.com/R91bP2qa https://pastebin.com/R91bP2qa
- rwnspace 7y agoI too prefer fizzy history. It's like Sodastream for your shell! Skim [0] is a nice alternative to fzf [1], mainly for the fact you can call additional commands dynamically like so [2]: sk --ansi -i -c 'rg --color=always --line-number "{}"' [0] https://github.com/lotabout/skim https://github.com/lotabout/skim [1] https://github.com/lotabout/skim#difference-to-fzf https://github.com/lotabout/skim#difference-to-fzf [2] https://github.com/lotabout/skim#interactive-mode https://github.com/lotabout/skim#interactive-mode
- ptzz 7y agoWould that correspond to piping the output of the additional command to fzf?
- lcnmrn 7y agoI like fd more. fish already has autocomplete.
- raykooyenga 7y agoI max out my history sizes as well as have bash functions to dump/persist them to time stamped archives on command or on logout.
- saagarjha 7y ago(That’s export HISTSIZE= export HISTFILESIZE= for those wondering how to do it.)
- xpuente 7y agoxargs should be there. The most useful tool IMO.
- based2 7y agohttps://en.wikipedia.org/wiki/Xargs https://en.wikipedia.org/wiki/Xargs
- JNRowe 7y agoAs zsh is mentioned at various points throughout the article I'll add that zargs¹ is often a great alternative to xargs. Combined with zsh's awesome globbing and filtering functionality it is often far nicer to work with than find. 1. https://github.com/zsh-users/zsh/blob/master/Functions/Misc/zargs https://github.com/zsh-users/zsh/blob/master/Functions/Misc/... or zshcontrib(1)
- jerzyt 7y agoI think zsh is the best shell ever, unfortunately, I've reverted to bash, because it's too much hassle to install zsh everywhere I work. zsh globbing is on another level.
- JNRowe 7y ago> zsh globbing is on another level. I agree. That said I'll freely admit that liberal use of glob modifiers and qualifiers can lead to the appearance of line noise. Because of that I'll occasionally unroll them with `find(1)`-syntax if I post a snippet to help a co-worker, but love their expressiveness when in an interactive session. For people not familiar with the extensive globbing options of zsh see https://linux.die.net/man/1/zshexpn https://linux.die.net/man/1/zshexpn .
- aludeman 7y agoyou may want to look at https://github.com/romkatv/zsh-bin https://github.com/romkatv/zsh-bin. roman also has some tooling which helps when ssh-ing to remote servers without zsh.
- lolive 7y agoWhoever can point me at a robust method to save/restore bash histories of a tmux session would save my life!!! [And yes i use tmux inside tmux]
- Klasiaster 7y agoI use this to have all shells share a history concurrently - which sometimes is confusing if you press "↑" and have an unexpected (possibly dangerous command) but I'm used to it now: shopt -s histappend PROMPT_COMMAND="history -a; history -c; history -r" See more about it here: https://unix.stackexchange.com/questions/1288/preserve-bash-history-in-multiple-terminal-windows https://unix.stackexchange.com/questions/1288/preserve-bash-...
- notyourday 7y agoAbout a year ago I went further into this rabbit hole and right now I think I am on a re-iteration of a system I have not changed in about 4 months. It came to me after watching too much sci-fi that had clicky-clicky-typie-typie instant recall. It occurred to me that every hack around history just nibbles at the edges probably because all of them are bolted on a design when the systems were slow. Systems now are fast and have good connectivity ( at least to themselves ) hence: "All logins across all systems that have the same security domain share single common command history." I use bash but it should be adoptable to anything. Here's how it works: 1. There's a database. I use redis because it is fast and has SETNX. [I may switch this to a redis queue to be able to archive commands as well.] 2. Using PROMPT_COMMAND variable I execute a function that pulls the last executed command using "history 1" and pushes it into the database. SETNX ensures that only a command that has not been seen before is stored. In the same transaction I trim the number of commands stored in the database to 5000. 3. Ctrl-R is bound to fetching last 5000 commands from the database, piping it into "peco" which I use with the selection line on a top ("fzf" does not support the top line so I don't use it here. "peco" does not support certain header skips/treatments, so i use "fzf" in other places ) 4. On a failure to push into the database, system does nothing as the data is in a local history. 5. On a failure to pull from the database, system feeds the result of the local history into the "peco". This system gives me ability to access the same command line history across my laptops, workstation, VMs, random Linux devices that i have running at home. Our ops-team uses it across all the monitoring workstations
- based2 7y agovi :x grep -n ... vi +§
- jpxw 7y ago> If you want to remove a sensitive command from your history, you can simply edit your $HISTFILE history file and remove it. It’s already too late at this point. Anybody on your machine can read the commands you are running, for example with ps. You should instinctively avoid entering anything in plaintext into a terminal which you don’t want other people to see. Any command line tool worth its salt will provide alternative ways of passing secrets (using configuration files for example).
- cassiet 7y agoHow exactly?
- jedimastert 7y agoI think what OP meant was closer to "if it could have been entered into the bash history than there's other ways it could be seen". Most CLI programs that need sensetive information as input should either do it interactively (a la sudo), as standard input, or configuration file. If worst comes to very worst, you can put the sensitive info in a text file and use backticks. For example: some-command --username=jedimastert --password=`cat secret.txt`
- lmz 7y agoHow would backticks help with hiding it from ps?
- jedimastert 7y agoI thought that's how it would show up in ps. Apparently I was incorrect. :(
- fooblat 7y ago> some-command --username=jedimastert --password=`cat secret.txt` This will not work in the way that you suggest. The output of ps will show the result of `cat secret.txt` and thus reveal the password.
- kubanczyk 7y agoTwo big ones missing. After ctl-r history search: ctl-o ctl-o ctl-o re-execute the history one by one alt-. alt-. alt-. last argument (better ux than that !$ business)
- deleted 7y ago[deleted]
- rkangel 7y agoI didn't know either of those, thanks!
- celeritascelery 7y agoNo matter how many times I read articles like this I always manage to learn something new. For example this time I learned about brace expansion. Will save me retyping a bunch of commands with different text.
- alufers 7y agoThe single best shell productivity tip for me was to use z: https://github.com/rupa/z https://github.com/rupa/z It automatically makes a list of directories you frequently use in your shell and if you type `z a-small-substring-of-the-directory-path` it does a cd to that directory. (e.g. I type `z and` and it changes my current directory to $HOME/Work/Projects/android`). Saved me tons of typing.
- Spivak 7y agoA somewhat less fancy version of this is $CDPATH. export CDPATH="/path/to/my/projects:$HOME/Work/Projects" # From anywhere. cd andr<tab><enter>
- mceachen 7y agoNote that CDPATH can break shell scripts that assume `cd` hasn't been adulterated. A huge block of "unalias" calls at the beginning of shell scripts used to be a common practice, but they don't seem to be found in more widely-used tools these days.
- kubanczyk 7y agoExcept with CDPATH the `cd` is usually not an alias. Even `/usr/bin/cd` is aware of CDPATH. It's a bug in the script, just like reacting badly to $IFS or $LANG.
- sigjuice 7y agoWhat is /usr/bin/cd for? cd is supposed to be a shell built-in, because running /usr/bin/cd will make another process and that cannot change the current working directory of the shell you are in. EDIT: $ cat /usr/bin/cd #!/usr/bin/sh builtin cd "$@"
- saagarjha 7y agoLook, it's 'cperciva! $ cat /usr/bin/cd #!/bin/sh # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $ # This file is in the public domain. builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"}
- alektorophobiae 7y agoset -o vi to use vi on the command line.
- jwilk 7y ago> Toggle your cursor between its current position and the beginning of line That's quite not what ^X^X does. The bash man page says: Swap the point with the mark. The current cursor position is set to the saved position, and the old cursor position is saved as the mark.
- AlexCoventry 7y agoAnd it's worth noting that Ctrl-Space sets the mark to the current position, just like in emacs. (TIL!)
- mstudio 7y agofishshell is my favorite productivity enhancer for the terminal: https://fishshell.com/ https://fishshell.com/ The primary reason I chose over zsh/bash was that autocompletion just works. If you install it, I highly recommend oh-my-fish as well, which allows you to add packages for look/functionality: https://github.com/oh-my-fish/oh-my-fish https://github.com/oh-my-fish/oh-my-fish If you're a zsh user, they have a similar framework: oh-my-zsh: https://github.com/ohmyzsh/ohmyzsh https://github.com/ohmyzsh/ohmyzsh
- ASTP001 7y agoI really enjoyed using fish for a short while, but soon I learned that it was not POSIX compliant. This was a deal breaker for me since my colleagues would often share scripts that wouldn't just work for me. I use zsh nowadays.
- JNRowe 7y agoI love zsh, but it isn't without its own strange quirks that make compatibility exciting at times. In a thread from a fortnight ago¹, RANDOM is handled very differently for example. Try `echo $(echo $RANDOM) $(echo $RANDOM)` in zsh and bash. I'm unsure whether minor differences that catch you out occasionally are worse than huge differences that you always have to think about. For me zsh still wins ;) 1. https://news.ycombinator.com/item?id=22841259 https://news.ycombinator.com/item?id=22841259
- tasuki 7y agoWow! Even repeating that call always yields the same result in zsh - as long as it's a subshell. I think your comment will save my sorry ass one day.
- LEARAX 7y agoWell, you could always just use a shebang or call bash/sh directly on the file.
- 7y ago
- fitzn 7y agoThe article links to this at the bottom, but just calling it out again because I think it's so useful. I am using git all the time---probably a majority of my terminal relates to git in some way. I think the git bash completion script is extremely useful. https://github.com/git/git/tree/master/contrib/completion https://github.com/git/git/tree/master/contrib/completion It's incredibly easy (and transparent) to "install" and saves a ton of keystrokes.
- mceachen 7y agoOn more handy set of emacs-derived keystrokes: Ctrl-a ctrl-k to clear the current command, or redo a hidden password prompt if you know you fat-fingered it. ctrl-a jumps the cursor to the beginning of the line, and ctrl-k deletes from current position to the end of the line. The mnemonic to remember these: "a" is the first position in the alphabet, and jumps you to the first position. "K" is short for "kill.”
- wazoox 7y agoCtrl-u (delete everything from the cursor to the beginning of line) is one less stroke for the very same result :)
- usrme 7y agoCtrl+U is also really handy for clearing password (or any other input) lines where you know you made a mistake, but don't want to just spam Backspace until you think you've gotten to the beginning.
- Axsuul 7y agoAny ideas why ctrl+k doesn't work in my iTerm2? All other readline shortcuts work.
- asicsp 7y agoI rarely use Ctrl+r to get command from history, because most of the time I know the starting characters of the command I need. So, I type those characters and use arrows keys to match from history. This is enabled via these settings in .inputrc # use up and down arrow to match search history based on typed starting text "\e[A": history-search-backward "\e[B": history-search-forward I also changed couple of setting wrt Tab autocompletion: # when using Tab for completion, ignore case set completion-ignore-case on # single Tab press will complete if unique, display multiple completions otherwise set show-all-if-ambiguous on
- codegladiator 7y agoYou can use ctrl+r for commands which are similar (say ssh to n number of servers, so the up/down would still take some amount of browsing the options) Just tag commands with a # at the end > $ complex command here # tagHere Later use the tag with ctrl+r I do this all the time > ssh 127.0.0.1 # master
- asicsp 7y agoyep, ctrl+r is better suited for such cases or whenever you have to match a command other than starting characters and I think there are some fuzzy matching options (like fzf) that can be added to ctrl+r
- tasuki 7y agoWhen I used bash, I had all of your settings on (had more, some others I can live without - these four I can't). I still have them in .inputrc for programs that use readline! I have since switched to zsh. Up/down to search history, in ~/.zshrc: [[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" history-beginning-search-backward [[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" history-beginning-search-forward Autocompletion in zsh is a different beast altogether :)
- seemslegit 7y agoBest shell productivity trick ever: don't use the shell for anything more complicated than launching executables and use a reasonably modern programming language to achieve all other tasks.
- wasdfff 7y agoWhat is a reasonably modern language? Everything seems to be at least 20 years old now.
- bhaak 7y agoOP might have made their statements tongue in cheek. But there's the truth in there that even programming languages that are 20 years old had a completely different mindset applied to their design process than the original Unix shell which was much more ad-hoc. 40 years ago IT was a completey different environment than 20 years ago.
- seemslegit 7y agoNot tongue in cheek at all, python might be 20 years old but is continually developed, has come all the way to have a typing system and has a huge ecosystem for all things devops
- serf 7y agono thanks. 'rename .txt _1.txt *' is quite a few lines in a language that's super simple, like Python, and it turns into code golf with even more terse languages. I'll stick to the terminal.
- kortex 7y ago> anything more complicated than launching executables mv is a simple executable. GP is talking about stuff like generating reports or sophisticated orchestration in .sh
- jabl 7y ago
- usefulcat 7y agoIf you care about your command history, I would advise against doing this unless you are truly a sed expert: $ sed -i '/secret-command/d' $HISTFILE # deletion of history line containing 'secret-command' Because if you get it even slightly wrong, you could easily hose your entire history. If it were me, I would just use an editor to delete that line (or two, if timestamps are enabled).
- wazzaps 7y agoAnd if you know don't want a command in your history, prefix it with a space.
- arendtio 7y agoToday, was actually the first time that I used the vim time travel feature. I noticed that I had deleted a line by accident somewhen during the last few minutes. So I typed :earlier 5m and copied the line. Afterward, I typed :later 5m and was back where I started, ready to paste the missing line :-)
- ryangittins 7y agoOn mornings when I'm feeling particularly lazy in the office, I'll do :later 8h and commit the code before heading home. ;)
- fdw 7y agoSome plugins that saved me lots of typing with zsh: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/history-substring-search https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/histo... looks through your history and only shows entries that started with the same characters that you already typed. Similar to Ctrl-R with fzf, but still similar enough that I use both. https://github.com/zsh-users/zsh-autosuggestions https://github.com/zsh-users/zsh-autosuggestions also looks through your history for commands with the same start, but it will automatically suggest them for you to use. If you often use the same commands, this saves quite some typing. For bonus points, I hooked it up so that Ctrl-Return will execute the suggestion. https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/per-directory-history https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/per-d... To make the first two even more powerful, I split my history based on the directory I'm in. This means that it's only suggesting me commands I entered before in this directory.
- zeppelin101 7y agoI'm a huge fan of the first 2 plugins, but I didn't know about the per-directory history plugin. I might put that in my toolbox. Thanks for the recommendation!
- kortex 7y agoMy productivity stack: Zsh (with all the autocomplete plugins) Oh-my-zsh zsh-autosuggestions: https://github.com/zsh-users/zsh-autosuggestions https://github.com/zsh-users/zsh-autosuggestions Tmux Histdb: https://github.com/larkery/zsh-histdb https://github.com/larkery/zsh-histdb Zoxide (replace cd): https://github.com/ajeetdsouza/zoxide https://github.com/ajeetdsouza/zoxide Fzf Rip (replace rm): https://github.com/nivekuil/rip https://github.com/nivekuil/rip My personal dotfiles: https://github.com/xkortex/bashbox https://github.com/xkortex/bashbox Mosh (replaces/augments ssh) What I'm currently looking for is a better multi-host logging solution.
- l0b0 7y ago** is not "expanded to all files and directories in the children directories, with a depth limit of 1." It's hard to see using `ls` because `ls` doesn't just list its arguments, it also lists files inside its directory arguments. Use echo ** and you'll see it just expands to the same as * - all the files in the current directory. Or type ** and press Ctrl-x, Ctrl-* (glob-expand-word) to expand it. After `shopt -s globstar` ** expands to all files recursively. Also, `echo $dir | tr '[:lower:]' '[:upper:]'` should be `printf '%s' "$dir" | tr '[:lower:]' '[:upper:]'` to handle spaces and other weirdness in file names. (If anyone knows how to escape asterisks in HN it would be helpful to know :)
- kmarc 7y agoMy productivity tip: Sit down, and read through `man bash`. Thank me later.
- hattori 7y agoNot built-in but hstr (https://github.com/dvorka/hstr https://github.com/dvorka/hstr) and tldr (https://github.com/tldr-pages/tldr https://github.com/tldr-pages/tldr) are awesome.