Useful Command Line Tips


I have been compiling all of the noteworthy command line tools I have come across in a Note on my Mac, and thought that it would be nice to compile my notes in a post. Share the wealth, right?

Example usage for each command is provided. I will continuously update this page as I find more useful commands.

Basic Movement / Text Entry

Okay, I know we’re starting slow, but these are three useful key bindings that you may use on any terminal.

  • Move the cursor to the beginning of the line – Ctrl + a
  • Move the cursor to the end of the line – Ctrl + e
  • Delete the line – Ctrl + u.

Scheduling tasks (Linux)

Scheduled tasks (aka cron jobs) are programs that run at a certain recurring time. I use this to backup my server and run Snapraid‘s sync job. To edit the cron jobs, run the following in a terminal

$ crontab -e

which will open your default text editor (likely vim), and will edit /var/spool/cron/crontabs/[username], which should not be edited manually (Source).

This is a space-delimited text file. The column headers are as follows:

minute hour day month day-of-week command

The day of the week is a number between 0 and 7, with both 0 and 7 meaning Sunday. A star designates every value of the field (i.e. * in the hour column means execute the command every hour) Some examples:

Run a command every day at 3am

0 3 * * * [command]

Run a command on April 9 at noon

0 12 9 4 * [command]

You can specify multiple field values by separating them with commas. Think of commas as saying, “and.”

Run a command at 17:00 on the 1st and 15th of February and September

0 17 1,15 2,9 * [command]

Using the slash(’/‘) character followed by a number runs the command that much less often.

Run a command every other hour

0 */2 * * * [command]

Run a command every third hour

0 */3 * * * [command]

Crontab Validation (added 2/7/16)

I recently discovered a website, crontab.guru, that will translate cron schedule expressions to an easy to understand statement. I highly recommend it!

Symlinks allow you to create an alias to a local file or directory from another directory. I use this when I want to store a large file or directory on a larger external drive and preserve my boot disk’s directory structure.

$ ln -s /destination /link name

This works for files and directories.

To rename a symlink, use the -f (force) parameter, which effectively removes the existing link before creating the new one.

Aliases (added 12/23/15)

If you commonly find yourself typing a long command, you may want to consider adding an alias for that command. To add an alias, append

alias [alias name]="[command]"

to ~/.bashrc. After saving ~/.bashrc with your new alias, the following command must run before using the new alias:

$ source ~/.bashrc

Here are some of the useful aliases I have created on my server:

  • alias ins="sudo apt-get install"
  • alias h="history"
  • alias c="clear"
  • alias grep="grep --color -n"
  • alias df="df -h"
  • alias du="du -sh"
  • alias sc="source $HOME/.bashrc"

You may notice that I added an alias called sc as an alternative to running source ~/.bashrc.

Ignore Alias (added 1/21/16)

To run a command without using its alias, such as running just df without the -h parameter, prepend a \ to the command.

$ \df

Install debs (debian-based Linux distros)

Sometimes the aptitude package manager doesn’t have the program you need, and you need to install a deb package manually. Run this command to install the program after you have downloaded it.

$ sudo dpkg -i [package.deb]

Git commands

While I was working on my Hearts Scoreboard, I mistakenly committed using my work email address many commits before HEAD. I found this useful command, which will find any commits that match the criteria specified on the first line and apply the changes you wish to the author information.

Here is how I changed all of the commits with christopher.rung@verato.com (my work email address) to clrung@gmail.com:

$ git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "christopher.rung@verato.com" ]; then
GIT_AUTHOR_EMAIL=clrung@gmail.com;
GIT_AUTHOR_NAME="Christopher Rung";
GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

It worked perfectly! I just needed to run

$ git push --force

after the operation to update the changes on Github.

Transfer files to/from remote machine

Download a file

$ scp your_username@remotehost.edu:/remote/file /local/file

Upload a file

$ scp /local/file your_username@remotehost.edu:/remote/file

Upload a directory

To download or upload directories, use the -r parameter.

$ scp -r /local/directory your_username@remotehost.edu:/remote/directory

SSH Tunneling (added 1/20/16)

This is super cool. If you are away from your server and would like to access an application that is running on a port on your server, but didn’t configure your router’s port forwarding settings, you can still access that application through an SSH tunnel.

$ ssh -N [user]@[IP address] -L [local port]:[local address]:[remote port]
  • -N - instructs SSH not to execute a remote command
  • -L - specifies that the remote port will be routed to the local port at the local address.

Example: To open port 1234 on my server and access it from localhost:4321 in my local web browser, I would execute the following command.

$ ssh -N clrung@christopherrung.com -L 4321:localhost:1234

Show 10 largest files in a directory

The pipe to head defaults to showing the top 10 items. To change this, use the -n (or --lines) parameter. bash $ du -h * | sort -hr | head

Rename files

Imagine uploading a batch of photos to your computer, and each picture has the format IMG_00134.jpg. To change these filenames to something more descriptive in a batch, run the following command. This command uses a regular expression to find the bash $ rename s/"IMG_"/"Ski Trip 2/13/15 "/ *

Delete files more than t days old

$ find /path/to/directory/* -mtime +t -exec rm {} \;

Re-run previous command as root

!! – read “bang bang” – is an alias for the last command you ran. This is very useful when, for example, you forget to run a command as root and get a Permission denied message.

$ cat /path/to/protected/file.txt

Shoot… I need superuser privileges to read that file.

$ sudo !!

This effectively runs

$ sudo cat /path/to/protected/file.txt

List disk names and mount points (added 1/25/16)

The lsblk command came in handy when I noticed high write activity to /dev/sdf1 in glances and wanted to know the mount point of the drive (since the mount point is a friendlier name).

$ lsblk
...
sdf      8:80   0 698.7G  0 disk
└─sdf1   8:81   0 698.7G  0 part /media/timemachine
...

As you can see, this is my Time Machine drive, so this write activity was due to one of my Macs backing itself up to my server.

Execute time consuming commands (added 2/9/16)

The screen command is a powerful tool that allows you to essentially have multiple terminal windows open in one window. It is useful for long operations, such as copying, moving, or downloading large files.

Before executing a long command, run

$ screen

screen will display a welcome message, which can be dismissed by pressing the Return key. After that, a regular bash prompt will appear. Start your long command

$ cp /hugeFile /media/drive1/

Next, press Ctrl-A and then the d key. You will see a message indicating that you have been detatched, such as the following, and then present you with your prompt.

[detached from 30568.pts-1.server]
$

To reattach to the old screen, run

$ screen -r

To leave screen, either press Ctrl-A and then the K (uppercase) key to kill the screen, or type exit in the prompt.

You may have multiple screens open at the same time. To list the open screens, run the following.

$ screen -ls
There are screens on:
5037.pts-1.server   (02/9/2016 09:34:00 PM) (Detached)
30568.pts-1.server  (02/9/2016 09:04:20 PM) (Detached)

To re-attach to a specific screen, provide screen with the screen session id (5037 and 30538 in the example above). To re-attach to screen 5037.pts-1.server, run the following.

$ screen -r 5037

If multiple screens are detatched, screen -r by itself will not work. It will output the available screens, similar to the screen -ls commmand.

There are many more commands that you can use with screen; press Ctrl-A and then the ? key to see all of the available commands.

Check if directory contains files (added 5/9/16) (adapted from StackOverflow)

#!/bin/sh
if find /path/to/directory -mindepth 1 -print -quit | grep -q .; then
     echo not empty
else
     echo empty
fi

Determine which process is using a port (added 8/23/16)

If you see Connection Refused messages, the lsof command might help you troubleshoot.

$ lsof -i tcp:[port number]

Example:

$ lsof -i tcp:8000
COMMAND  PID             USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    2965 christopher.rung    5u  IPv4 0xd7c43881a3d71863      0t0  TCP *:irdmi (LISTEN)

To kill the process, I can run kill 2965.

Get WAN IP address via Terminal (added 4/13/17)

$ curl -s http://whatismyip.akamai.com/

That’s it for now! Please let me know if you have any questions or corrections.