//Tips tagged bash
Latest tips by RSS
Click here to subscribe
Follow Shell-Fu on Twitter
Click here to follow
Follow Shell-Fu on identi.ca
Click here to follow
Using expansion to move a file aside without having to type the file name twice

cp ReallyLongFileNameYouDontWantToTypeTwice{,.orig}


View Comments »


Don't forget the bash fork bomb. DO NOT TRY THIS AT HOME... Posted here so that you don't see this in a forum or a mailing list and use it without knowing:

$ :(){ :|:& };:


Explanation:
:()
defines a function called : (accepts no arguments)
{ :|:& };
This is the function: It calls the function itself and pipes the output to the same function ":" and puts the process in the background. (Recursive invocation) with ; it ends the function definition
:
Calls the function and creates havoc.

- Emre


View Comments »

This is a little known and very underrated shell variable. CDPATH does for the cd built-in what PATH does for executables. By setting this wisely, you can cut down on the number of key-strokes you enter per day.

For example:
$ export CDPATH='.:~:/usr/local/apache/htdocs:/disk/backups'

Now, whenever you use the cd command, bash will check all the directories in the $CDPATH list for matches to the directory name.


View Comments »

multiple command output into a single program:

diff -u <(ls -c1 dir_1) <(ls -c1 dir_2)

Will show you a diff of files in the root of dir_1 and dir_2


View Comments »

Selected Bash Keystrokes:
Ctrl-U - Cuts everything to the left
Ctrl-W - Cuts the word to the left
Ctrl-Y - Pastes what's in the buffer
Ctrl-A - Go to beginning of line
Ctrl-E - Go to end of line


View Comments »

From dotfiles.org; original author unknown:

###   Handy Extract Program

extract () {
    if [ -f $1 ] ; then
        case $1 in
            *.tar.bz2)   tar xvjf $1        ;;
            *.tar.gz)    tar xvzf $1     ;;
            *.bz2)       bunzip2 $1       ;;
            *.rar)       unrar x $1     ;;
            *.gz)        gunzip $1     ;;
            *.tar)       tar xvf $1        ;;
            *.tbz2)      tar xvjf $1      ;;
            *.tgz)       tar xvzf $1       ;;
            *.zip)       unzip $1     ;;
            *.Z)         uncompress $1  ;;
            *.7z)        7z x $1    ;;
            *)           echo "'$1' cannot be extracted via >extract<" ;;
        esac
    else
        echo "'$1' is not a valid file"
    fi
}


View Comments »

This is a simpler password generator.

< /dev/urandom tr -dc A-Za-z0-9_ | head -c8

Note that the 'tr' strips out everything except characters in the ranges (alphanumeric, mixed case and underscores). This is a nice approach as piping to head means the minimum number of bytes required to generate a password of appropriate length are taken from /dev/urandom vs other methods which take more than you should need but still have a chance of not having obtained enough random data to generate a password of the required length. You can change the parameter to head to get passwords of any length.


View Comments »

Rename replaces string X in a set of file names with string Y.

rename 's/.html$/.php/' *.html


This will change the extension of every .html file in your CWD to .php.


View Comments »

Put the following in your .bashrc file

function calc { echo "${1}"|bc -l; }


Usage:
$ calc 2+2
4
$ calc "sqrt(2)"
1.41421356237309504880


View Comments »

Simulate a never-ending compilation so you have an excuse for why you're browsing the net (see http://xkcd.com/303/):

while true; do awk '{ print ; system("let R=$RANDOM%10; sleep $R") }' compiler.log; done


When you want to kill it, CTRL-C won't work. You have to suspend it (CTRL-Z) then kill the job (kill %1).


View Comments »


I often use 'screen' to run a command that I want to leave running when I logout but sometimes I forget and kick off a long job without screen. If you want to keep these things running, the following command will close the shell keeping all subprocess running

disown -a && exit

More information on the bash man page:

man bash | grep -A9 "disown \["


View Comments »

To remove empty directories (even if filenames or dirnames contain spaces or weird characters) from a tree you can do:


find . -type d -empty -print0 | xargs -0 rmdir


View Comments »

If, like me, you often make mistakes on the command line, try using the history shortcut '^^' to repeat the last command with changes.

For example:

$ cat fiel
cat: fiel: No such file or directory
$ ^el^le
cat file


View Comments »

I'm frequently logged into multiple different boxes concurrently. To help me keep track of which box I'm working on at the moment, I have this in my .bashrc file, which I keep rsynced across the various boxes.


# defines the color variables used below, including ${Normal} # google "tput setaf" and "tput setab" for more information . ~/.colors.sh if [ `id -u` -eq 0 ]; then Color=${RedBG}${White} # red background for root else case `hostname` in machine1 ) Color=${Blue} ;; machine2 ) Color=${Green} ;; machine3 ) Color=${Cyan} ;; machine4 ) Color=${Purple} ;; * ) Color=${Yellow} ;; esac fi PS1="${Color}$PS1${Normal}\n> "


.colors.sh:

Black="$(tput setaf 0)"
BlackBG="$(tput setab 0)"
DarkGrey="$(tput bold ; tput setaf 0)"
LightGrey="$(tput setaf 7)"
LightGreyBG="$(tput setab 7)"
White="$(tput bold ; tput setaf 7)"
Red="$(tput setaf 1)"
RedBG="$(tput setab 1)"
LightRed="$(tput bold ; tput setaf 1)"
Green="$(tput setaf 2)"
GreenBG="$(tput setab 2)"
LightGreen="$(tput bold ; tput setaf 2)"
Brown="$(tput setaf 3)"
BrownBG="$(tput setab 3)"
Yellow="$(tput bold ; tput setaf 3)"
Blue="$(tput setaf 4)"
BlueBG="$(tput setab 4)"
LightBlue="$(tput bold ; tput setaf 4)"
Purple="$(tput setaf 5)"
PurpleBG="$(tput setab 5)"
Pink="$(tput bold ; tput setaf 5)"
Cyan="$(tput setaf 6)"
CyanBG="$(tput setab 6)"
LightCyan="$(tput bold ; tput setaf 6)"
Normal="$(tput sgr0)" # No Color


View Comments »

Often I find myself using Ctrl-R in Bash to get an old command, only to find that too many days have passed and it's no longer in the .bash_history file.

It is possible to increase the number of lines in the history file, but there can always be a moment when you'll need a long command from many months ago. The solution below uses the PROMPT_COMMAND variable, a command that bash executes before showing each prompt. Here are the two lines to add to your profile:

export HISTTIMEFORMAT="%s "

PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }"'echo $$ $USER \ "$(history 1)" >> ~/.bash_permanent_history'


If a previous PROMPT_COMMAND was set, it gets executed before this and then appends a line of the format:

PID USER INDEX TIMESTAMP COMMAND

to a file called .bash_permanent_history in the current user home.

Adding the username is useful to distinguish between "sudo -s" sessions and normal sessions which retain the same value for "~/", and so append lines to the same .bash_permanent_history file.


View Comments »

The following bash script, which depends on lynx web browser, uses Google's reverse geocode service to find a nearby address given a latitude and longitude pair:

#!/bin/bash
# findnearest
# Usage: findnearest latitude longitude
# Ex.  findnearest  17.976227 -66.111016

lat=$1
long=$2
result=$(lynx -dump "http://maps.google.com/maps/geo?output=csv&oe=utf-8&ll=$lat,$long")
echo $result | cut -f3- -d,


View Comments »

ssh -l <login> -L <port>:<destination:port> <proxymachine> <local addy>
example
ssh -l foo -L 5000:192.168.5.2:443 192.168.1.1 https://localhost:5000/


Then go to https://localhost:<port>/ to get to destination's website; through the proxy machine.



View Comments »

To find the last modified files in a directory you can use ls -ltr. To find the last modified file on a file system it will not work, but the following command will work:

find /etc -type f -printf "%T@ %T+ %p" | sort -n


View Comments »

To change the extension on a group of files using only bash builtins and mv:

for i in *.txt; do mv $i ${i%%.txt}.html; done


View Comments »

Find all files with given name (you can use Bash expansion if you'd like), and Grep for a phrase:
find . -name  -exec grep "phrase" {} \;


To display the filename that contained a match, use -print:
find . -name  -exec grep "phrase" {} \; -print


Or, use Grep options to print the filename and line number for each match:
find . -name  -exec grep -Hn "phrase" {} \;


The string `{}` is replaced by the current filename being processed everywhere it occurs in the arguments to the command. See the `find` man page for more information.


View Comments »

Q: If I resize my xterm while another program is running, why doesn't bash notice the change?
http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)

Bash won't get SIGWINCH if another process is in the foreground.
Enable checkwinsize so that bash will check the terminal size when
it regains control.

Put this in your bash config somewhere (e.g. Gentoo has it in /etc/bash/bashrc):

shopt -s checkwinsize


View Comments »

The script below will truncate the $PWD to 1/4 of the terminal width and put it into the command prompt, all within the same bash process, no forks to tr and gawk.

function truncate_pwd

{
newPWD="${PWD/#$HOME/~}"
local pwdmaxlen=$((${COLUMNS:-80}/4))
if [ ${#newPWD} -gt $pwdmaxlen ]
then
newPWD=".+${newPWD: -$pwdmaxlen}"
fi
}

PROMPT_COMMAND=truncate_pwd
PS1="${ttyname}@\h:\${newPWD}\\$ "



View Comments »

If you're working in bash and want to quit without saving your history, you can do so using:

kill -9 $$

$$ gives the pid of the current bash instance, and the kill ends the process. There are other ways of disabling history in bash, but this can be used with no forward planning and any time/place you like.


View Comments »

These handy one-liners are used to perform the famous Caesar cipher encryption where letters of the alphabet are shifted by differing margins. The same tr command can be used to encrypt and decrypt encoded files/strings.

Rot-13 encryption:
(file)
$ cat file|tr A-Za-z N-ZA-Mn-za-m

(string)
$ echo -n "Secret Msg"|tr A-Za-z N-ZA-Mn-za-m


Rot-47 encryption:
(file)
$ cat file|tr '!-~' 'P-~!-O'

(string)
$ echo -n "Secret Msg"|tr '!-~' 'P-~!-O'


View Comments »

For a fix of #67 that is a bit nicer

for support spaces in the arguments just fine, just make sure you quote "$i".

$ touch a

$ touch b\ c

$ for i in *; do ls "$i"; done;



View Comments »



Home Latest Browse Top 25 Random Hall Of Fame Contact Submit