Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Badassify your terminal and shell (jilles.me)
52 points by merih on Nov 5, 2014 | hide | past | favorite | 52 comments


I don't want my terminal badassified; I want to get work done. Rather than bling out my command prompt I simply try to do what real developer, data, and sysadmin badasses do:

* Learn your shell language -- really learn it. Learn how to fit programs together, how to manage jobs, and all of the control structures in your shell language. Avail yourself of aliases and shell functions.

* Learn the Unix command set, sed, and awk. Practice using these tools to do complex data or textual manipulation tasks.

* Make a personal ~/bin directory and add it to your $PATH. Put shell scripts that do useful things in there.

* Learn enough of a real programming language such as C or Python to write small programs to do common things that would be slow or cumbersome to do in shell. Put them in your ~/bin.

There, you'll be Unixing like a boss with a minimum of prompt ricing.


Agreed with everything you list here. I do think it's valuable to learn how to pretty-up and polish the shell prompt. I've set mine up to display the time as well as the exit status of the previous command, along with the usual tidbits of user, host, and cwd.

In terms of languages to learn, the most important is your shell, generally bash for most people. 99% of the time, bash is Fast Enough, even though it can often be very slow. Bash is incredibly ugly, but using its features and the userland tools that are standard on most Unices, you can do a lot of amazing things relatively easily.

For speedy programs, Perl can't be beat. For text manipulation, even C programs sometimes run slower than Perl and generally require more code and are much harder to maintain. Perl is nearly as ugly as Bash and has even more annoyances, but for raw text-processing throughput there's no competition.


Right, sure - but you definitely - well, probably ;) - still want iTerm2!

For Linux, try terminator: http://gnometerminator.blogspot.co.uk/p/introduction.html , or your package manager. There are doubtless tons of other options.


Why do you definitely still want iTerm2?

The only feature that I find even remotely compelling is mouse support, but so few programs handle mouse input that it largely doesn't matter. People always mention split panes, but I've never had a desire to vertically split my terminal window. If I ever did have such a desire, I'd probably just use tmux. And yes, iTerm2 claims to have some form of tmux integration, but I believe that's basically just using iTerm2 split panes to represent tmux panes, and I don't get why that's any better than just using tmux directly.

So besides mouse support and split panes, what does iTerm2 offer that Terminal.app doesn't? Some of the answers I've heard in the past are "256 colors" and "color themes", both of which Terminal.app supports.


I've tried using iTerm2's tmux support and found it to actually be less friendly than just using tmux directly. Definitely a YMMV thing, I suppose, but I was seriously baffled.

One thing I heard from several people in a previous discussion is that iTerm2 makes a thin outline around the terminal window and since they often have overlapping terminal windows (that are presumably opaque with black backgrounds), Terminal wasn't as usable. This has changed with Yosemite's Terminal, though.


Huh, I never noticed the very thin outline around Terminal windows in Yosemite. Neat. I've been using a slightly-transparent dark background with blur for years (which gets slightly more transparent for background windows). That always made it really easy to visually distinguish overlapping windows. But I can see the border being useful for people who have completely opaque windows (with black backgrounds).


I use split panes all the time. Never got on with terminal multiplexers myself. Other stuff I like about iTerm2:

- configurable word boundaries for word selection by mouse

- X-style copy/paste (middle click to paste current selection)

- dabbrev-style word completion from current buffer, though I've not ended up finding this as useful as it seems it should be

But if you don't value any of this, then maybe you don't want it? Let me edit my post to fix this.


Thanks for the response. But yeah, none of that sounds like things I'd want. Especially X-style copy/paste, I'm really glad Terminal.app doesn't do that (although interestingly, middle-click actually does paste the OS clipboard, but there's no auto-copy of selected text).


I don't use a Mac, and on Linux I use plain xterm. Does the job, is fast, and you can spawn a lot of them cheaply. Arranging them is easy with a tiling wm.


all of your bullet points are excellent advice, but:

having timestamps in my prompts has helped me straighten out what I did to get myself into a situation across a few different windows of a tmux session.

having all nonzero return codes show up automatically because of tweaking my oh-my-zsh configuration has definitely saved me time here and there.

root on my machines looks completely different visually compared to my regular user account(s) and this has stopped me from doing dumb things as root, again, while bouncing around in a tmux session.


I've done all of the above, and I've blinged out my prompt. They're not mutually exclusive :)


Using the world's most common shell in a standard configuration comes with benefits, too. Incredible portability of your code & experience.

Plus shells that try to be too smart or do too much always break, leaving you debugging your shell. Shoot me now.


"X's that try to be too smart or do too much always break, leaving you debugging your X" is, based on my observations, a true statement for values of X equal to ANY core system component: package manager, init system, build system, etc.


Agreed.

I would add 'grep' in there as an absolute must have.

The sed, grep, awk holy trinity will allow you to do pretty much any type of text manipulation and searching that you can imagine.


I have one more that I like. I call it 'rex' and it basically allows me to do a regex substitution on command line text (not stdin, but actual command line args). It mostly comes in handy when looping over files in a directory where I want to do some kind of processing based on information in the file name. For example, I can tag all of the episodes of a podcast with their track numbers (several podcasts I listen to don't do id3tags) with this command:

    for f in *.mp3; 
      do id3v2 -T `rex 's/^[^0-9]*([0-9]+).*\.mp3$/\1/` $f; 
    done
The script itself is really simple, but I can post the source if anybody's interested.


Warning for newer developers:

I confused myself much more than was necessary when I was first starting out, because I started using all of these tools like zshell/oh-my-zsh before I understood what was really going on, specifically with my $PATH. I seriously spent about a month floundering and becoming increasingly frustrated and confused before I finally sat down, read the docs, and learned why I should have been putting stuff in ~/.zshrc instead of ~/.bashrc as a result of using zshell. If you're still learning the ropes, customizations like this can be dangerous and time-consuming. Or, at least, you won't be able to just do whatever the intro docs tell you to do on GitHub and expect things to work. Those are hoops you don't want to jump through when you're first starting out.

For the more experienced hackers, this warning probably seems amateurish and unnecessary, but when I was starting I would have been particularly interested in "badassify-ing" my developer toolkit, not realizing what I was screwing up and how difficult I was making my future life.


Would you say it's worth switching to/learning zsh itself? My default has been /bin/bash for years and years and I find I'm too slow while I'm trying to learn zsh.

Plus, if you spin up an image on EC2 or DigitalOcean, the default will be bash.


I recently installed fish shell after about 15 years of bash usage. I don’t think I’ll ever go back to bash on my PC.

I never really customized bash, and fish has so good defaults that I don’t think I'll customize it much.

Web site: http://fishshell.com/


Here is the thing. Bash is the default on most of the servers you are going to have to work on,. Centos, RedHat, Fedora, Debian, Arch,. etc. So knowing and using Bash is kind of like knowing English in the business world.

Of course, don't let that detract from the usefulness of other shells out there. They can be fun and educational.


Wow. Just looked at the fish docs and it takes the two reasons I almost started using zsh/omz for, syntax highlighting and completion, and by the looks of it blows the zsh versions out of the water.


The completion is excellent. It just works.


With Powerful Software comes ever-tempting Yak Shaving.


One thing I like about zsh that doesn't seem to get that much attention (and seems to be overlooked here) is path expansion.

If you're typing a path (let's say to ~/Dropbox/Public/...) you can say "cd ~/d/p" and hit tab to fill in even the intermediate parts. Given that the only path that matches "~/d./p." is ~/Dropbox/Public/, zsh will fill that in. If it hits an ambiguity down the proverbial road, it'll expand until it hits the ambiguity and list potential matches.

It's really convenient knowing that I can say something like "cd ~/d/c/s/c" and it'll fill in the rest.

edit: I tried to indicate a basic regex pattern but I think HN is reading it as trying to italicize "/p." instead. I later tried escaping it with backslash, but no luck. Sorry if that's really confusing.


bash has had this feature too since its first public release. bfox copied from twenex, which may have gotten it someplace else. Twenex had a great JSYS (system call) that did full command argument completion that was the inspiration for the readline library


And what happens when you have to use the terminal on a machine that hasn't been "badassified"?


Yes. Things should not be customized because not everything is customized. Personally, when I drive a car I never adjust the seat or mirror positions. I also never store anyone's contact info in my phone because then I wouldn't know what to do if I lost my phone.

Seriously though, having aliases, scripts, or complex programs to help doesn't cripple you unless those things themselves force you into a state you are unable to reach out of.

I've never found myself on a new machine feeling helpless because I didn't have a shell with all the customizations I'm used to; I only felt some annoyance. Said annoyance was far less than the cumulative annoyance I felt before making those changes--and the amount they have saved me since.


I copy this into the boring terminal and run it: https://gist.github.com/AlexanderSelzer/ba487126454672a6596d

There's no zsh or iTerm2, but it is much easier to read. I guess it would be possible to make something that downloads the binaries, sets them up temporarily and opens them.


Things aren't as pretty, a lot of unnecessary <Tab>'s are pressed, and you sometimes have to Google things other people may instinctively know. I don't mind the Googling so much -- if it's important enough, I'll eventually learn it.


Always bring your bag of tricks with you. I have an easy to reach shellscript that I source when on a new/loaned shell. That way I can get my aliases, prompts, functions and everything else I've built to make my life easier.


Not much. If you do this you are usually pretty used to a normal terminal. I usually just tab way more then i should in bash. Thats it.


Exactly ... Back to basics.

Just learn how to use the terminal in its default form. We've been doing it for years efficiently.


Dude. Optimize for your 99% use case. I spend ten minutes a week on someone else's machine. Does that really make it a bad idea to remove warts and add niceties to my machine? Assuming you aren't literally a stump it should be easy enough to go back to the defaults.


I wonder if it says something about how brittle software and their interactions tend to be: many very experienced computer users tend to promote a certain minimalism. Not for minimalism's sake, but apparently because their computers are in such a delicate and brittle state that any superfluous may brake it, and they have to expend a lot of effort to get it back to that same state. And also the fact that they aren't able to customize whatever other machine they have to use for any considerable time, probably because the administrator won't let you tweak anything (again, because it might break/introduce vulnerabilities etc. Again, it's in a brittle state).


I disagree. You should be able to use a basic terminal, but you're not living your developer life in a series of hotels - most of the work you're doing is probably on your own machine.


sshrc or similar


You take a few minutes to get used to/remember how to use that terminal?

Not all of us are system administrators who need to be able to work on any Unix system at any times notice, and can only rely on things like ed being installed on them (That's at least the complaint I've read a lot of from people who are against some customization, or learning some kind of non-standardized/ubiquitous program. But what if you get stranded in the Sahara with no laptop, and you have to use a AT&T UNIX PC because the bedouins don't have anything else, and you desperately need to fix something on some boxes 1,000 miles away? Where's your fancy colour schemes new?).


Please do not pipe code from random downloads into your shell!


Instead, only run code from random sites that put time into having a legitimate looking UI and/or price tag.

Edit: I do wholeheartedly agree with the revised parent comment. Piping things into your shell is bad practice because it allows malicious and non-malicious risks to your system. In the malicious case, an attacker can very easily serve up an innocent script to your browser and a malicious script to curl/wget. In the non-malicious case, a break in networking midway through the download can truncate commands, turning "rm -rf /opt/coolsoftware/build" into "rm -rf /opt".


Wow, you made me realize I somehow didn't at all write what I meant. I was referring to piping downloads into a shell. I've updated my comment. Thank you.


If you really want to "badassify" your shell, check out twosheds, a library that I wrote for making shells in Python. [1] My motivation was that learning bash scripting sucks, and it's hard to do many things that should be easy (like automatically running a command when certain conditions change). With twosheds, it's just Python, so the limit is your imagination.

twosheds still needs some work to get POSIX compliance, but it's already usable enough that I've replaced bash with my custom shell, Shell, which I've hacked to, among other things, print a ton on information on Git's status and the file system-- I never type git status or ls anymore. [2] If this sounds interesting, I encourage you to fork it and give it a try.

[1]: https://github.com/Ceasar/twosheds

[2]: https://github.com/Ceasar/Shell


Three suggestions:

(1) Don't use words like "badassify" — they make you sound immature and reduce your credibility. (c.f. "rockstar engineer", "coding ninja", et cetera)

(2) Invest an afternoon in switching to a static site generator — your site's current server appears to be on fire due to excess traffic. As a member of the getpelican.com dev team, I'm clearly biased, but any static site generator will be better than an uncached Ghost instance.

(3) Try Fish :^) http://hackercodex.com/guide/install-fish-shell-mac-ubuntu/


I switched from oh-my-zsh to [Prezto][1] and I couldn't be happier. I hope this is useful to some of you.

[1]: https://github.com/sorin-ionescu/prezto


Say what you will about the whole post, but the z script is very neat - https://github.com/rupa/z


Never heard of zsh-syntax-highlighting before, pretty cool feature! Apparently it's in zprezto, if you want to enable it, just add

      'syntax-highlighting' \
to your .zpreztorc (below "zstyle ':prezto:load' pmodule \" line)

and uncomment

    zstyle ':prezto:module:syntax-highlighting' highlighters \
      'main' \
      'brackets' \
      'pattern' \
      'cursor' \
      'root'


I'm actually not convinced by kitchen-sink approaches like oh-my-zsh. It has so much stuff in it... where do you even begin (except for passive discoverability stuff like completion -- that's always good to have).

I would be more tempted by adding a few things at a time, piece-wise. Plundering oh-my-zsh could be an approach: add some parts, see if they're useful, if they fit in your workflow, else ruthlessly discard them.


Instead of using the z script, why not just use cd and $CDPATH, which are built in? I have mine set to this:

export CDPATH=.:$HOME:$HOME/workspace:$HOME/gocode/src/github.com/geetarista

You can set it to whatever you want, then just use `cd` and not worry about using some other script.


Some mention of using Tmux (or screen) and powerline would have also been good.



Very cool stuff. thanks


I went to look at some of the amazing zsh plugins, and found this endorsement flashing in front of me: "I just can't imagine not using oh-my-zsh. I can believe I won't have to mess around with .bashrc again."

And then I wondered: what on earth are you doing in the command line if you don't want to "mess around with .bashrc"?

I guess the point is to turn the CLI into a mouse-less GUI?


Or the fact that it asks you to install iTerm. My favorite thing about Terminal.app is that it's already there, just a spotlite command away, and you can theme it as well.


I personally think that is a moot point because there's usually a whole bunch of things that I need to install on a Mac, or any system for that matter, before I can actually be productive on it. At work we have a few shell scripts that we run through which will install homebrew, various software, and finally I grab my dotfiles. A full setup usually only takes an hour or two.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: