I've been investing some time in the command line on my Mac. I am moving from a dilettante going to the shell on a per-need basis to a more seasoned terminal native. It pays off handesomely! It's hard to convey how nice it to have to have a keyboard-based unified environment instead of a series of disjoined mouse-based GUI experiences.
Here are some recommendations pertaining to mastering the command line on a Mac specifically:
-You can make the terminal start instantaneously instead of it taking several seconds. Remove the .asl files in /private/var/log/asl/. Also remove the file /users/<username>/Library/Preferences/com.apple.terminal.plist
- Install iterm2. It possesses many fancy features but honestly I hardly ever use them. The main reason to use it instead of the default Terminal application is that It just works©.
-Make your terminal look gorgeous. It may sound superficial but it actually is important when you spend expanded period of time in the terminal. You go from this http://i.imgur.com/cx3zZL8.png to this http://i.imgur.com/MQbx8yK.png . You become eager to go to your terminal instead of reluctant. Pick a nice color scheme https://code.google.com/p/iterm2/wiki/ColorGallery . Use a nice font (Monaco, Source Code Pro, Inconsolata are popular). Make it anti aliased.
-Go fullscreen. Not so much for the real estate but for the mental switch. Fullscreen mode is a way to immerse yourself into your productive development world. No browser, no mail, no application notification. Only code.
-Install Alfred. It's the command line for the GUI/Apple part of your system. Since I installed it I stopped using the dock and Spotlight. Press ⌘+space then type what you want and it comes up. In just a few keystrokes you can open an application, open gmail/twitter/imdb/..., make a webs search, find a file (by name, by text content), open a directory,... It's difficult to describe how empowering it is to being able to go from 'I want to check something out in the directory x which is somewhere deep deep in my dev folders' to having it displayed in 2 seconds flat.
-Make a few symlinks from your home directory to the directories you use frequently. Instead of doing cd this/that/code/python/project/ you just do cd ~/project.
-Learn the shell. I recommend the (free) book The Linux Command Line: http://linuxcommand.org/tlcl.php . It guides you gently from simple directory navigation all the way up to shell scripting.
-Use tmux. Essential if you want to spend some time in the terminal. You can split the window in multiple independent panes. Your screen will have multiple terminals displayed simultaneously that you can edit independently. For example I'll have the code in one side and on the other side a REPL or a browser. You can also have multiple windows each with its own set of panes and switch from on to the other. With the multiple windows I can switch from one aspect of a project to another instantly. E.g: one window for the front-end dev, a second one for the backend and another for misc file management/git/whatever.
-Pick an editor and work towards mastery. I don't care if you choose vi or emacs. You'll be surprised how simple features can make a big change in how you type. You'll be even more surprised at how good it feels
The terminal is here to stay. It's a skill that bears a lot of fruits and that deprecate slowly. The more you sow the more you reap.
What's wrong with the default Terminal application? I use it daily and have been for close to a decade. I never found myself wishing it did anything than what it already does.
> -Use tmux.
Meh. For most people screen works just as well. Perhaps more importantly, you can rely on screen being available pretty much anywhere. Just like vim. Speaking of which: vim is great. Use vim. The world needs more vim.
It seems that as more languages are created that include native repl experiences, emacs becomes more appealing to me because it fits nicely with editor+repl, where in other editors a repl seems more of an afterthought or nice-to-have.
I would say definitely learn vim first, but it's great to know both vim and emacs. It just opens up more doors.
tmux does vertical and horizontal splitting better than screen.
That's my rationale for using iTerm2 and tmux instead of Terminal.app and screen.
(yes, I'm aware that screen has improved its splitting recently, but I switched to tmux in 2011, after seeing a presentation about it by Nicholas Marriott)
> Speaking of which: vim is great. Use vim. The world needs more vim.
Agreed :)
export MARKPATH=$HOME/.marks
function jump {
cd -P $MARKPATH/$1 2>/dev/null || echo "No such mark: $1"
}
function mark {
mkdir -p $MARKPATH; ln -s $(pwd) $MARKPATH/$1
}
function unmark {
rm -if "$MARKPATH/$1"
}
function marks {
ls -l $MARKPATH | sed 's/ / /g' | cut -d' ' -f9- | sed 's/ -/ -/g' && echo
}
function _marks {
reply=($(ls $MARKPATH))
}
compctl -K _marks jump
compctl -K _marks unmark
Now to remember a directory you type % mark <any_string>
and to jump to that directory you type % jump <any_string>
To list all your shortcuts % marks
Depending on the version of ls you might have to change the -f9 parameter to -f8 for marks functionshttps://github.com/mattgreen/dotfiles/blob/master/zsh/jump.z...
https://github.com/robbyrussell/oh-my-zsh/wiki/Cheatsheet http://www.quora.com/zsh/What-are-the-cool-features-of-zsh-t...
I'd also install autojump https://github.com/joelthelion/autojump to jump quickly between directories instead of using symlinks. Instead of cd ~/project, you just do j project, or maybe j proj is enough for autojump to know where you want to go.
Terminal has started instantaneously on all my Macs for years, since the advent of SSDs. A tiny fraction of a second.
If it is taking several seconds to launch, I think something must have gone haywire somewhere.
Turns out the option to maintain ALL HISTORY EVER as scrollback was turned on. So he had the last year of compiler output and whatnot stored in a file somewhere, getting loaded into memory the first time he launched Terminal after a boot, and then eating a big chunk of his laptop's memory. Turning off the option was a major improvement.
So, like any unix os, ensure you do this:
touch $HOME/.hushlogin
That will short circuit that stuff. Like you said I've not had issues with terminals opening fast but it can't hurt. I don't give a rats when I last logged in on any unix os I log into.
Also set up case insensitive completion, saves the extra shift press for all those Mac paths.
To set this up, add `set completion-ignore-case on` to your `~/.inputrc` file (create it if it doesn't exist).
It's called jump/mark. I aliased j to jump and added tab completion to zsh and it's made all the difference.
Usage
Mark .
Marks the current directory to be in the jump list.
Jump <dir name>
Jumps to that directory.
Zsh is a much nicer shell than bash too and there are no glaring incompatibility issues I have seen in daily usage.
export MARKPATH=$HOME/.marks
function jump {
cd -P $MARKPATH/$1 2> /dev/null || (echo "No such mark: $1" && marks)
}
function mark {
mkdir -p $MARKPATH; ln -s $(pwd) $MARKPATH/$1
}
function unmark {
rm -i $MARKPATH/$1
}
function marks {
ls -l $MARKPATH | sed 's/ / /g' | cut -d' ' -f9- && echo
}
_jump()
{
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "$( ls $MARKPATH )" -- $cur) )
}
complete -F _jump jumpBasically there is a jump oh-my-zsh plugin, but be sure to add the auto-completion mentioned in this article too...
http://juanreyero.com/hacker-ways/index.html
HN is not the target audience, but it might be helpful for somebody.
This is an excellent point and one that's not nearly as appreciated as it should be. Fullscreen mode was written off in Lion as an example of Apple dumbing down the platform and making it more like iOS, but it's the perfect mode for writers, coders--and really just about any kind of creator who needs to focus.
Which reminds me, I really will go and pay my 13 bucks for it now, it's more than worth it. But the free version is fully functional with just an occasional nag screen.
It's too late for me anyway - I have moved to Alfred, the new kid on the block at the time, and like it much more (much less clutter). Plus, I can't trust the QS developer anymore after he's abandoned the project once.
I also think this sentiment will be growing. I think there's a large disconnect between "traditional" UNIX users and people entering from the web / Rails / other kinds of worlds, and that gap is slowly shrinking. That's why we are seeing things like npm tools (bower, grunt) replacing makefiles, Docker replacing traditional sysops, the whole idea of "DevOps" as a thing vs "IT".
I'm very very excited about this transition and want to help be a part of it. I think I'm going to write a similar tutorial outlining my current mac / terminal workflow.
alias cdss='cd /Users/username/somewhere1/somewhere2'
then I just go 'cdss' to get there from anywhere.
You can fix that properly in two steps:
1. Create a symlink to your preferred shell. E.g. `sudo ln -s /bin/bash /usr/bin/bash`
2. In Terminal Preferences, use /usr/bin/bash as your shell, instead of the default login shell.
To confirm that you've fixed the problem:
- Open a new terminal window.
- "Last login" should NOT be displayed.
- Hit Command+I to show the inspector. The command should read: login -pfq username /usr/bin/bash.
The -q switch on /bin/login is what speeds things up. (.hushlogin does not solve the problem)
In order to get Terminal to pass the -q switch to /bin/login you have to use a non-standard shell, hence the symlink.
If you are using ZSH, you can just append paths to the $cdpath environment variable. This will allow you to "cd name-of-project" (assuming you've added your project directory to $cdpath). No need for a mess of symlinks in this case.
[1] http://www.skamphausen.de/cgi-bin/ska/CDargs
[2] brew install cdargs
parse_git_branch() { git branch 2> /dev/null | sed -e '/^[^]/d' -e 's/ \(.*\)/(\1)/' }
export PS1="\u@\h \[\033[32m\]\$(parse_git_branch)\[\033[00m\] \W $ "
GUI emacs does brings nice features: -multiple fonts / font sizes at the same time (nice for minimap http://www.emacswiki.org/emacs/MiniMap !) -more shortcut possibilities with s- added to the usual C- and M-- -more colours
Shell/ansi-term modes don't work well enough. There's always problems with shortcuts/encoding/escape sequences/Ncurse.
The way i work now is that i have a bunch of terminal tabs open. Each tab has a shell which pretty much just sits in a single directory. If i need to switch to a different directory, i switch tabs. A nice effect of this is that each tab builds up a recent shell history specific to the directory it sits in; the shell in the source directory has a history full of build commands, the shell in the installation directory has a history full of start and stop commands, and so on.
This works because i generally use a fairly small (<10) set of different directories, and i don't move between directories much as part of a single task. Partly, this is because i use qualified paths rather than cd'ing around everywhere. I am happy writing (mostly, tab-completing):
vi lib/awesomeapp/dns/client.rb
Whereas a colleague of mine would always do: cd lib
cd awesomeapp
cd dns
vi client.rb
He might get a lot of mileage out of pushd/popd. But for me, it just optimises something i don't spend a lot of time doing.Easy enough to change in system preferences, though. And with using Vim NERDtree, or some other directory plugin, it makes sitting at the top level directory of your project, with multiple projects in multiple tabs, pretty easy.
Are you on Mac? If so, have you done anything to make tab-switching easier/faster? I'm interested because I only recently set mine up this way, and am always open to more efficient methods.
$ pwd
/tmp
$ mkdir -p a/b/c
$ ( cd a/b/c ; pwd )
/tmp/a/b/c
$ pwd
/tmpIf you haven't tried it, I highly recommend z. It's impossible to Google for, but it's oh-so-convenient.
setopt autopushd
to have cd work like pushd.And
setopt pushdignoredups
is probably helpful too as it will not push the same directory multiple times on the stack.pushd .
cd some_dir
Some examples here:
http://en.wikipedia.org/wiki/Pushd_and_popd
Edit: change to desktop Wikipedia URL.
The only bad thing about it that "port upgrade outdated" must be used carefully, but that is probably true of most port-like systems.
The Homebrew maintainers think that linking against Apple's libraries is better, because you need to install less stuff.
The MacPorts maintainers used to agree, several years ago, and used to do just that. Then, Apple released a software update which changed some libraries and broke everyone's MacPorts installations. So then they changed their mind. Now, they think that linking against their own, coherently managed, set of libraries is better, because Apple can't break stuff.
To me, Homebrew just looks like an exercise in reproducing others' work without learning from their experiences. I don't see any advantages to it myself.
Less fundamentally, there's also quite a difference in the number of packages. MacPorts's homepage indicates that they have 18530 ports. An ls|wc in Homebrew's repository indicates that they have 2802 formulae. That said, i suspect that 95% of what people actually need is in the collection that Homebrew has.
I like the way Fink [1] uses the /sw (software) directory.
Does anyone have a valuable opinion on the comparison between Fink and Homebrew — or maybe MacPorts?
* A large number of pre-built binary packages with an apt-get style command (pkgin) to install them. Over 10,000 packages are available for OSX in the most recent release (2014Q1).
* It is cross-platform to over 20 different platforms. At Joyent we provide binary packages for SmartOS/illumos, OSX, and Linux, so you can use identical packaging tools across multiple platforms, rather than having to use different tools on each OS. It is the default package manager on SmartOS, with over 12,000 binary packages available for that platform.
* As the 'src' in 'pkgsrc' implies, it's very easy to build from source too if you want to tweak build options or compiler flags. You can also install into any prefix you desire (we default to /usr/pkg), even as an unprivileged user to your home directory.
Our binary packages are available from http://pkgsrc.joyent.com/installing.html and we'd love to hear feedback on how to improve them or adding support for different platforms.
I ended up making a /rr tree ("rwg's root"), building things I care about from scratch, and using GNU stow to manage it.
That was an early blocker for me as well; however, when I discovered that I could just install homebrew at ~/.homebrew, that made it all work out.
I created https://github.com/wilmoore/homebrew-home to automate this; however, you technically don't need this install script as you could do it yourself if you really wanted to. I like it because I no longer have to think about it.
That said, you can configure homebrew to use any path (check the wiki), you just have to set other environment variables as needed (eg, PATH). For example I'm currently using /opt/homebrew.
(note: a large downside to this is that you have to compile everything and cannot take advantage of Homebrew's pre-compiled "bottles" for some packages)
Homebrew is, by far, the most pleasant package manager I have ever used.
I couldn't even tell you why, but it's just nicely designed, and shit just tends to work. Part of it is that it targets a very well-defined system (MacOS), and it has an explicit aim to integrate with that system as well as possible. (I guess this could be true of e.g. apt on ubuntu, but ha ha ha.)
As an example, most package managers have some funky, one-off , more-or-less shitty way to update the packages list. Homebrew has...git! Which works great.
I highly recommend checking it out.
Another example: Most package managers say, "you're installing random software off the internet? Better give it root access!" Homebrew installs as the current user, no root access. Much saner default policy, IMO.
Or maybe you want to see a list of installed packages? "brew list". Oh, you wanted one-per-line, that's "brew list -1", just like ls.
Or maybe you want to install some software from a 3rd party repo? "brew tap $somewhere; brew install $something".
It's just a very thoughtful, well-made piece of software. Strongly recommend checking it out.
Try this out: say hello -v Good
say -v cellos "Dum dum dum dum dum dum dum he he he ho ho ho fa lah lah lah lah lah lah fa lah full hoo hoo hoo"
wc -l < /usr/share/dict/words | xargs -I {} jot -r {} 100000 | paste -d " " - /usr/share/dict/words | sort | awk '{print $2 "! "}' | say gshuf /usr/share/dict/words | head -n 10 | awk '{print $1 "! "}' | saysay -v '?' (This gives you a list of voices)
say -v Good (This let's you type in a stream of text)
say --interactive=/green spending each day the color of the leaves ssh somehost
cd /some/dir
grep -lr foo . | remote_pbcopy
I guess something like this is possible with GNU Screen or with Tmux, and perhaps the Tmux/iTerm interaction helps, but I've never figured it out. ssh somehost 'cd /some/dir; grep -lr foo .' | pbcopy
not very flexible, but it works for many cases ssh -R 19999:localhost:22 remote_host
On the remote host: command_that_prints_stuff | ssh localhost -p 19999 pbcopy
________The first command routes the port 19999 on the remote host to port 22 on the computer you're using.
ssh part on the second command connects to 19999 (and thus 22 on your computer) and runs the pbcopy command in the current shell (which is the pipe from command_that_prints_stuff)
ssh -x example.com
cat /var/log/syslog | grep event | xclip -i
Your X clipboard will be shared with the host so the output will be placed into your local clipboard. open /Applications/Safari.app/
as an example, when open -a safari
does the same thing. cmd+space safari cmd+space sa <return>
For most people. Because it seems to prioritise based on frequency of past selection.Edit: looks like this is actually built into zsh. Slightly surprised, but just goes to show I know almost nothing about the shell I use every day.
I wrote related rant once[0] when I tried to debug an issue of a misconfigured default browser.
It's incredibly handy.
The Linux equivalent of `open` is `xdg-open`. I usually alias it to `op`, since `/bin/open` exists.
Another bit of terminal-sugar for OS X users:
alias lock='/System/Library/CoreServices/"Menu Extras"/User.menu/Contents/Resources/CGSession -suspend'
And most Linux users: alias lock='gnome-screensaver-command -l'
If you find yourself accidentally triggering hot corners, the lock command is your savior.I've sorta-documented this stuff over the years, but only for my own memory. https://gist.github.com/ggreer/3251885 contains some of my notes for what I do with a clean install of OS X. Some of the utility links are dated, but fixing the animation times really improves my quality of life.
One tiny thing though, at the bottom it says
> Recall that OS X apps are not true executables, but actually special directories (bundles) with the extension .app. open is the only way to launch these programs from the command line.
Actually, you can launch them in other ways. Example
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/Users/<username>/temp/delmechrome --no-first-run
Will start a new instance of Chrome with it's own datastore in ~/temp/delmechrome. add some URL to the end to have it auto launch some webpage. Delete ~/temp/delmechrome to start over.The open command does allow you to specify command-line arguments to pass to the application (via --args), which is generally a safer way to do things.
So, doing Foo.app/Contents/MacOS/Foo is often the only way to launch a GUI app while inheriting the full environment that you have on the command line.
I often have to do this to launch various developer tools, and have them be able to inherent important environment variables, e.g. database credentials or secrets,
Right now I am more interested in creating simple visual interfaces on top of UNIX-y tools, for my own personal use cases. The main benefit of this is the ability to better experiment with and optimize my workflows for different properties as needed through different combinations of single responsibility interfaces and single responsibility programs.
I am sensing that there is great promise in seeing much higher APMs (actions per minute) for many tasks, even compared to the all-powerful command line. Also, there are lots of interesting possibilities for better visual representations of data to improve comprehension and usability.
This is a genuine question - personally, i find command line interfaces to be far more hackable than graphical ones, so i would expect the opposite to be true, and hence i'm interested in your perspective.
I still think textual interfaces are a great thing for those reasons, but I don't believe they are the best thing in many cases. Yes, they are very capable and customizable, but have serious weaknesses with usability, especially when working with data of higher dimension.
I don't really think of it as text versus graphics, but rather an issue of data being represented in its best form for doing some particular work with it, and having the best interfaces to those different forms and the work. The traditional one-domain/one-application GUI model is unsustainable for this purpose, and has the weakness of constant context shifting. Composable visual interfaces are an anti-application paradigm, and more focused on data flow. To avoid problems with pure visual programming environments, symbols would still be considered the best representation for certain work (like editing text and working with logic).
Basically it's a command-line front end to Apple's TextKit file import/export library. Works with a bunch of rich text/word processor formats, including OpenDoc, RTF, HTML 5, and MS Word. Critically, the HTML it emits is vastly better than the bloated crap that comes out of Microsoft Word or LibreOffice when you save as HTML ...
Install pandoc and multimarkdown as well and you've got the three pillars of a powerful, easy-to-use multiformat text processing system.
(Annoyingly it doesn't provide a way to get at the guts of Apple's own Pages files. Which sucks because the only tools for transcoding Pages are Pages itself, and icloud.com.)
set editing-mode vi
set keymap vi-command
see more settings @ https://github.com/shawndumas/dotfiles/blob/master/readline/...To make this work for Python:
Add a file called .editrc with the following content:
bind -v
Add a file called .pythonrc with the following lines:
import rlcompleter import readline
Add a line to your .bashrc which makes Python run .pythonrc when it starts interactively:
export PYTHONSTARTUP="$HOME/.pythonrc"
Now Python will understand your vi keystrokes :-)
The original title is clearly more accurate / useful / canonical. The overwritten title is ambiguous. This is indeed not a list of every OS X command line utility.
I don't see any ambiguity. The article is precisely about OS X Command Line Utilities; it doesn't matter how many there are in the list. Nor is it misleading. There's no implication of completeness.
https://github.com/alloy/terminal-notifier
Add this to your .bashrc:
function notify { terminal-notifier -title "$1" -message "$2" }
It's super useful for keeping long running tasks running.
* lunchy: wrapper over launchctl, written in Ruby – https://github.com/mperham/lunchy
* brew cask: "«To install, drag this icon...» no more", as they say – https://github.com/caskroom/homebrew-cask
* have fun with "say" – https://github.com/andreis/different
It seems like a large portion of HN is less experienced re sysadmin, but is interested in it nonetheless. Perhaps there's room to make a 'codecademy for unix' type course? Curious to see what folks thing.
This is only tangentially related, but I recently wrote a little Automator Service to gather any selected file and folder paths from Finder. I very often need to grab the path of something for programming-related stuff, and doing it from the command line or with the mini-icon drag-and-drop takes way too long. Maybe somebody here will find it useful! http://cl.ly/1a3s3g1u2Q2w
"Select a window using your mouse, then capture its contents without the window’s drop shadow and copy the image to the clipboard:
$ screencapture -c W"
-c captures the cursor, W is not an option. The real command for this is: $ screencapture -C -o"cmd-a" "cmd-c" (copy all)
double click on a word I'm looking for, "cmd-e" to enter it into the find clipboard
'pbpaste | fgrep --color `pbpaste -pboard find`'
I have that aliased as 'pbg'.
Otherwise good article.
export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced
I thought that was one of the most amazing things when I used a linux system, but OS X is black and white by default.
That alone might be sufficient reason to migrate from ubuntu.
My co-workers and I used to ssh into the iMacs of non-technical users in our office and have a good laugh from a nearby room.
ssh-add -k keyfile
Integrates with keychain meaning you can have a passworded private key without having to play around with ssh-agent and shells and profiles. Put keychain access in the menu bar and you can lock the keychain on demand as well. Integration of ssh into the OSX workflow is absolutely awesome.That and some of the examples in that article really make it a killer platform for Unix bits.
10. /System/Library/CoreServices/Applications/Wireless Diagnostics (with built-in wifi stumbler)
11. /System/Library/CoreServices/Screen Sharing.app (Built-in VNC client with hardware acceleration)
12. /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources (Command-line wifi configuration and monitoring tool)
Combine with sed, awk, and cut, and these tools can provide useful monitoring.
~$ mdfind tag:Active kind:xcode
/Users/jn/Code/xyz/xyz.xcodeproj
...
Queries like this also work in the Cmd-Space UI, or as a Saved Search. By default each term is joined with AND, but you can specify OR too. $ mdf "*invoice*.pdf"
/Users/smw/Downloads/Invoice-0000006.pdf
https://gist.github.com/smw/a21a9f675ed3358830daFor example, I set the letter 'o' as an alias for 'open' on OS X, and to "thunar" on Xubuntu and "nemo" on Linux Mint.
function gocd {
cd `go list -f '{{.Dir}}' $1`
}
It uses the same syntax as go list to specify packages, so you can do, e.g.: ~ $ gocd .../markdownfmt
markdownfmt $ pwd
/Users/Dmitri/Dropbox/Work/2013/GoLand/src/github.com/shurcooL/markdownfmt
markdownfmt $ _
So nice.sips - https://developer.apple.com/library/Mac/documentation/Darwin...
osascript - https://developer.apple.com/library/mac/documentation/Darwin...