//Top 25 Tips
Want to show something on your machine to someone over the web? Don't copy it or upload it somewhere. Just run "webshare" and the current directory and everything beneath it will be served from a new web server listening on port 8000. When your pal is finished, hit control-c.
Listen on localhost:80, forward to localhost:81 and log both sides of the conversation to outflow, automatically restarting if the connection dies.
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
alias webshare='python -c "import SimpleHTTPServer;SimpleHTTPServer.test()"'
Want to show something on your machine to someone over the web? Don't copy it or upload it somewhere. Just run "webshare" and the current directory and everything beneath it will be served from a new web server listening on port 8000. When your pal is finished, hit control-c.
Using expansion to move a file aside without having to type the file name twice
cp ReallyLongFileNameYouDontWantToTypeTwice{,.orig}Running a second command with the same arguments as the previous command, use '!*' to repeat all arguments or '!:2' to use the second argument. '!$' uses the final argument.
$ cd /home/user/foo
cd: /home/user/foo: No such file or directory
$ mkdir !*
mkdir /home/user/foo
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:
- Emre
$ :(){ :|:& };:
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
Don't search history by grepping ~/.bash_history, or repeatedly hitting the up arrow, instead use CTRL+r (or '/' in vi-mode) for search-as-you type. You can immediately run the command by pressing Enter.
Place a filename at the beginning of the line to make it easier to edit the search at the end of the command.
$ </var/log/messages grep foo
$ </var/log/messages grep bar
$ </var/log/messages grep user1
Forget that your running as underprivileged? No need to retype the command.
> command_with_insufficient_permissions
Permission denied
> sudo !!
> command_with_insufficient_permissions
Permission denied
> sudo !!
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:
Now, whenever you use the cd command, bash will check all the directories in the $CDPATH list for matches to the directory name.
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.
This piece of code lists the size of every file and subdirectory of the current directory, much like du -sch ./* except the output is sorted by size, with larger files and directories at the end of the list. Useful to find where all that space goes.
du -sk ./* | sort -n | awk 'BEGIN{ pref[1]="K"; pref[2]="M"; pref[3]="G";} { total = total + $1; x = $1; y = 1; while( x > 1024 ) { x = (x + 1023)/1024; y++; } printf("%g%s\t%s\n",int(x*10)/10,pref[y],$2); } END { y = 1; while( total > 1024 ) { total = (total + 1023)/1024; y++; } printf("Total: %g%s\n",int(total*10)/10,pref[y]); }'
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
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
Use the -p option to mkdir and make all parent directories along with their children in a single command.
mkdir -p tmp/a/b/c
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
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
In bash (or anything using libreadline, such as mysql) press ALT+. to insert the last used parameter from the previous line.
Eg:
$ vim some/file.c
$ svn commit
Eg:
$ vim some/file.c
$ svn commit
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
}
I guess anyone who's administered several remote boxes has had the unfortunate problem of (when not thinking straight) taking down the network card on a machine you have no physical access to. The result being that the ssh session you used to connect dies. The typical mistake is to do something like (as root):
The unfortunate result being that the first statement disconnects your session and hangs up the chain resulting in the network not coming back up. A nice way around this is to use the bash "disown" builtin command, ie:
In this case you launch a backgrounded task that is disconneced from the session (meaning the ssh session dying won't kill the process) which sleeps for 5 seconds (to give the down a chance to happen) then configures the network card as appropriate and brings it back up. As soon as this launches and is disowned, then immediately takes the network card down. If the configuration change keeps the IP address the same, you'll find that after 5 seconds your bash prompt just comes back and the session resumes.
ifconfig eth0 down; ifconfig eth0 inet 123.4.5.6; ifconfig eth0 up
The unfortunate result being that the first statement disconnects your session and hangs up the chain resulting in the network not coming back up. A nice way around this is to use the bash "disown" builtin command, ie:
(sleep 5; ifconfig eth0 inet 123.4.5.6; ifconfig eth0 up)& disown -h $! ; ifconfig eth0 down
In this case you launch a backgrounded task that is disconneced from the session (meaning the ssh session dying won't kill the process) which sleeps for 5 seconds (to give the down a chance to happen) then configures the network card as appropriate and brings it back up. As soon as this launches and is disowned, then immediately takes the network card down. If the configuration change keeps the IP address the same, you'll find that after 5 seconds your bash prompt just comes back and the session resumes.
This is a simpler password generator.
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.
< /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.
If you want to tail the errors on another terminal, just push them to a fifo:
On your other terminal:
$ mkfifo cmderror
$ mycommand 2> cmderror
On your other terminal:
$ tail -f cmderror
mknod backpipe p; while nc -l -p 80 0<backpipe | tee -a inflow | \ nc localhost 81 | tee -a outflow 1>backpipe; do echo \"restarting\"; done
Listen on localhost:80, forward to localhost:81 and log both sides of the conversation to outflow, automatically restarting if the connection dies.
To delete a file who's file name is a pain to define (eg. ^H^H^H) find it's inode number with the command "ls -il". Use the line below to find and delete the file.
find . -inum 12345 | xargs rm
Use && to run a second command if and only if a first command succeeds:
cd tmp/a/b/c && tar xvf ~/archive.tar
Rename replaces string X in a set of file names with string Y.
This will change the extension of every .html file in your CWD to .php.
rename 's/.html$/.php/' *.html
This will change the extension of every .html file in your CWD to .php.
You can use ssh in conjunction with tar to pull an entire directory tree from a remote machine into your current directory:
ssh <username@sourcehost> tar cf - -C <sourcedir> . | tar xvf -
For example, let's say you have a "bsmith" account on a host called "apple". You want to copy those files into your "bobsmith" account on a host called "pear". You'd log into your "bobsmith@pear" account and type the following:
ssh bsmith@apple tar cf - -C /home/bsmith . | tar xvf -
This technique is useful when you have insufficient disk space on the source machine to make an intermediate tarball.
ssh <username@sourcehost> tar cf - -C <sourcedir> . | tar xvf -
For example, let's say you have a "bsmith" account on a host called "apple". You want to copy those files into your "bobsmith" account on a host called "pear". You'd log into your "bobsmith@pear" account and type the following:
ssh bsmith@apple tar cf - -C /home/bsmith . | tar xvf -
This technique is useful when you have insufficient disk space on the source machine to make an intermediate tarball.
Print a random shell-fu tip:
;-)
links -dump "http://www.shell-fu.org/lister.php?random" | grep -A 100 -- ----
;-)
This checks if a daemon is running, if not it starts the daemon. Great for daemons that need to always be running. Can be used with cron
ps -C someprogram || { someprogram & }
// sil at infiltrated dot net
ps -C someprogram || { someprogram & }
// sil at infiltrated dot net

