openiduser3
| Twitter name | TheHunInParis |
|---|---|
| Blog URL | http://titan2x.com/ |
| Homepage URL | http://titan2x.com/ |
Questions asked (still waiting for an answer)
How to cut out pages from a PDF file using ghostscript or other free command line tools
A single page, or multiple pages, preferably with tools that exist not only in Linux.
by openiduser3 on Jan. 31, 2012, 8:17 p.m.
Questions asked (marked answered)
How to send an http POST to a website with a file input field
I want to test submitting to a form on a website. Creating a POST request with curl or wget is probably easy, but how does it work if the form has a file field? I want to submit a file to a form.
by openiduser3 on Feb. 6, 2012, 7:31 a.m.
How to find all hard links to a file in Solaris or GNU/Linux systems?
by openiduser3 on Dec. 23, 2011, 9:13 a.m.
One-liners posted
Run a never-ending process in the background in a way that you can check on its status anytime
bash$ screen -d -m -S some_name ping my_router
Explanation
-d -mstartscreenin "detached" mode. This creates a new session but doesn't attach to it.-S some_namegives the screen session a label, so you can easily re-attach to it withscreen -R some_name- The shell prompt returns immediately, and of course you can logout too, the
screensession will continue to run happily. - When the specified program exits (in this example
ping), itsscreenwindow will also exit, and if there are no other windows in thescreensession, then thescreensession itself will also exit.
Make a hexdump or do the reverse with the xxd command
bash$ xxd /path/to/binary/file
Explanation
This shows a very nice hexdump of the specified file. You can edit the output and convert it back to binary with xxd -r. But the best part is that you can configure vim to do all the converting back and forth for you, effectively turning vim into a binary editor, by adding this to your .vimrc:
augroup Binary
au!
au BufReadPre *.bin let &bin=1
au BufReadPost *.bin if &bin | %!xxd
au BufReadPost *.bin set ft=xxd | endif
au BufWritePre *.bin if &bin | %!xxd -r
au BufWritePre *.bin endif
au BufWritePost *.bin if &bin | %!xxd
au BufWritePost *.bin set nomod | endif
augroup END
This will work for editing .bin files. To use it for other file extensions too, duplicate the lines within augroup and replace *.bin with *.exe for example.
This tip is from vim's :help xxd.
Really lazy way to print the first instance of $foo that occurs after $bar
bash$ ifconfig | grep ^en1 -A5 | grep inet | head -n 1
Explanation
This is just for the sake of an example of finding $foo that occurs after $bar. Substitute ifconfig and the arguments of grep appropriately for your use case.
- In the output of
ifconfigthere are several lines withinet. We want to get to the first one that comes after a line starting withen1 grep ^en1 -A5will print the line starting withen1and the next 5 lines that follow itgrep inetwill print only the lines matchinginethead -n 1will print only the first line
The value 5 in -A5 is really just a guess that the line we're interested in will be within the next 5 lines, the appropriate number depends on your use case.
Kind of a dumb technique, but it's easy to remember.
Replace symlinks with the actual files they are pointing at
bash$ find /path/to/dir -type l -exec sh -c 'cp --remove-destination "$(readlink "{}")" "{}"' \;
Explanation
- All the double quoting is necessary to handle filenames with spaces.
- Calling
shwith-execis necessary to evaluatereadlinkfor each symlink
Limitations
The BSD implementation of cp does not have the --remove-destination flag.
Expire a user's password immediately
bash$ chage -d 0 USERNAME
Explanation
This will effectively force the user to change his/her password at next login.
Limitations
Not in BSD. Yes in Linux. Don't know in UNIX.
Sort du output in Human-readable format
bash$ for i in G M K; do du -hsx * | grep "[0-9]$i\b" | sort -nr; done 2>/dev/null
Explanation
- The reason to use a
forloop is to sort results with G or M or K values separately, otherwisesort -nwould just sort everything by the numbers regardless of G M K suffix. grep "[0-9]$i\b"matches lines containing a digit followed by G or M or K followed by a "word boundary"
Convert a decimal number to octal, hexadecimal, binary, or anything
bash$ echo 'obase=2;1234' | bc
Explanation
bcis an arbitrary precision calculator language.obasedefines the conversion base for output numbers, in this example 2 (binary);is a statement separator inbc1234is the decimal number to convert- By piping the command to
bcwe get1234in binary format
Convert from avi format to mp4 encoding
bash$ ffmpeg -i file.avi file.mp4
Explanation
FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library.
Limitations
It is not a standard package in most systems and distros.
Format input into multiple columns, like a table, useful or pretty-printing
bash$ mount | column -t
Explanation
column is a utility for formatting text. With the -t flag it detects the number of columns in the input so it can format the text into a table-like format.
For more details see man column.
A simple function to conveniently extract columns from an input stream
bash$ col() { awk '{print $'$(echo $* | sed -e 's/ /,$/g')'}'; }
Explanation
Something I do a lot is extract columns from some input where cut is not suitable because the columns are separated by not a single character but multiple spaces or tabs. So I often do things like:
... | awk '{print $7, $8}'
... which is a lot of typing, additionally slowed down when typing symbols like '{}$ ... Using the simple one-line function above makes it easier and faster:
... | col 7 8
How it works:
- The one-liner defines a new function with name
col - The function will execute
awk, and it expects standard input (coming from a pipe or input redirection) - The function arguments are processed with
sedto use them withawk: replace all spaces with,$so that for example1 2 3becomes1,$2,$3, which is inserted into theawkcommand to become the well formatted shell command:awk '{print $1,$2,$3}'
Resize an image proportionally to some specified width or height
bash$ mogrify -geometry x31 path/to/image.gif
Explanation
mogrifyis part ofImageMagick, an image manipulation software suitemogrifymanipulates the specified images. If you prefer to keep the original image untouched and write the manipulated image to a different file, simply replacemogrifywithconvert, the syntax is the same, but the last command line argument will be the target image to write to.- The
-geometryflag is to resize the image, it requires a dimension parameter in the formatWIDTHxHEIGHT - The dimension in this example has no width, which means the image will be resized to height=31 pixels, and the width will be proportional.
Limitations
ImageMagick is not a standard package, though it is open source and available in many systems.
Do something in another directory without going there
bash$ (cd /path/to/somewhere; tar c .) > somewhere.tar
Explanation
As explained superbly in man bash:
(list) list is executed in a subshell environment (see COMMAND EXECU-
TION ENVIRONMENT below). Variable assignments and builtin com-
mands that affect the shell's environment do not remain in
effect after the command completes. The return status is the
exit status of list.
In other words, this is a handy way to do something somewhere else without having to go there and coming back.
Find the target path a symlink is pointing to
bash$ readlink a_symbolic_link_to_somewhere
Explanation
Sure, you could figure out the link target from the output of ls -l a_symbolic_link_to_somewhere too, but the output of readlink is simply the target of the symbolic link itself, so it is cleaner and easier to read.
Remove carriage return '\r' character in many files, without looping and intermediary files
bash$ vi +'bufdo set ff=unix' +'bufdo %s/^M$//' +q file1 file2 file3
Explanation
- The arguments starting with
+are commands invithat will be executed set ff=unixis a shortcut forset fileformat=unixand means to use "unix" file format, i.e. without the carriage return\rcharacter.%s/^M$//is a pattern substitution for all lines in the entire buffer, the pattern is "carriage return at end of the line", where^Mis not two literal characters but actually one, to enter it on the command line pressCtrlfollowed byEnter/Returnbufdomeans to run command in all buffers (each file is opened in a separate buffer)qis to quitvi
Note: the set ff=unix is necessary, otherwise the pattern substitution will not do anything if all the lines end with \r = the file is in dos format, because in that case the line ending character will not be considered as part of the line.
Note: if a shell-script has "accidentally" some carriage returns in it, then when you try to execute you may get an error: bad interpreter: No such file or directory. This one-liner fixes that problem. If you know that all the lines in the file have the carriage return, and there is only one file to fix, then a simplified version of the one-liner is enough:
vi +'set ff=unix' +wq file1
Get the octal, hexadecimal and decimal codes of the ASCII character set
bash$ man ascii
Explanation
Knowing the octal, hexadecimal or decimal code of the ASCII character set can be handy at times. In the past, too often I did things like:
perl -e 'for my $n (1 .. 255) { print $n, chr($n), $n, "\n"; }'
... when a simple man ascii would have done the trick...
On a related note, these all print the letter "A":
echo -e '\0101'
printf '\101'
printf '\x41'
perl -e 'print "\x41"'
Sort and remove duplicate lines in a file in one step without intermediary files
bash$ vi +'%!sort | uniq' +wq file.txt
Explanation
We open a file with vi and run two vi commands (specified with +):
%!sort | uniq%= range definition, it means all the lines in the current buffer.!= run filter for the range specified. Filter is an external program, in this examplesort | uniq
wq= write buffer contents to file and exit.
List or edit and re-execute commands from the history list
bash$ fc -l
Explanation
fc is a little known but very useful bash built-in.
fc -lwill list the most recent 16 commandsfcwill open the last command in a text editor defined in the environmental variableFCEDITorEDITORor elsevi, and re-execute when you exitfc 5 9will open the history entries 5 to 9 in a text editorfc -s pat=subwill run the last command after substitutingpatwithsubin it (does not open editor)fc -s pat=sub ccis the same but on the last command starting withccfc -s ccwill run the last command starting withcc
For more info see help fc.
Find the most recently modified files in a directory and all subdirectories
bash$ find /path/to/dir -type f -mtime -7 -print0 | xargs -0 ls -lt | head
Explanation
find /path/to/dir -type f -mtime -7 -print0prints all the files in the directory tree that have been modified within the last 7 days, with null character as the delimiterxargs -0 ls -ltexpects a null delimited list of filenames and will sort the files by modification time, in descending order from most recent to oldest- Since we are looking for the most recent files, with
headwe get the first 10 lines only
Note that if there are too many files in the output of find, xargs will run multiple ls -lt commands and the output will be incorrect. This is because the maximum command line length is getconf ARG_MAX and if this is exceeded xargs has to split the execution to multiple commands. So depending on your use case you may need to tweak the -mtime parameter to make sure there are not too many lines in the output.
List open files
bash$ lsof -n
Explanation
With the -n flag it will not try to resolve network numbers to host names for network files, making it run a bit faster.
With the -c option you can select processes executing a matching command. And with the -t flag the output will be simply process ids without a header, suitable to use with kill. For example you can kill Google Chrome process gone crazy like this:
kill -HUP $(lsof -n -c /google/i -t)
Here /google/i is a regular expression pattern with case insensitive matching.
Set a colorful bash prompt per dev test prod environments
bash$ PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '
Explanation
It is useful to set a different color for the shell prompt in different deployment environments like dev/test/production, so that you don't mix up your multiple windows and do something by accident in the wrong window.
PS1contains the format of the primary prompt\[\e[1;31m\]sets the foreground color to red\uwill be substituted with the current username\hwill be substituted with the hostname\Wwill be substituted with the current directory name\[\e[0m\]is the end marker of the color setting
To make the color stand out even more for root users, the inverse color can be interesting too:
PS1='\[\e[7;31m\][\u@\h \W]\$\[\e[0m\] '
Other color examples:
#PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' # green
#PS1='\[\e[1;33m\][\u@\h \W]\$\[\e[0m\] ' # yellow
#PS1='\[\e[1;34m\][\u@\h \W]\$\[\e[0m\] ' # blue
You can learn more in man bash, search for "PROMPTING".
Limitations
Your terminal program must support colors, of course ;-)
Print the lines of file2 that are missing in file1
bash$ grep -vxFf file1 file2
Explanation
-fis to specify a file with the list of patterns: file1-Fis to treat the patterns fixed strings, without using regular expressions-xis to match exactly the whole line-vis to select non-matching lines
The result is effectively the same as:
diff file1 file2 | grep '^>' | sed -e s/..//
Limitations
The flags of grep might work differently depending on the system. So yeah you might prefer the second way which should work everywhere. Nonetheless the various of flags of grep are interesting.
Find all the unique 4-letter words in a text
bash$ cat ipsum.txt | perl -ne 'print map("$_\n", m/\w+/g);' | tr A-Z a-z | sort | uniq | awk 'length($1) == 4 {print}'
Explanation
- The perl regex pattern
m/\w+/gwill match consecutive non-word characters, resulting in a list of all the words in the source string map("$_\n", @list)transforms a list, appending a new-line at the end of each elementtr A-Z a-ztransforms uppercase letters to lowercase- In awk,
length($1) == 4 {print}means: for lines matching the filter condition "length of the first column is 4", execute the block of code, in this case simply print
Concatenate PDF files using GhostScript
bash$ gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=output.pdf -dBATCH file1.pdf file2.pdf file3.pdf
Explanation
Free PDF editing software might become more and more available, but this method has been working for a long time, and likely will continue to do so.
Limitations
It may not work with all PDFs, for example files that don't conform to Adobe's published PDF specification.
Format text with long lines to text with fixed width
bash$ fmt -s -w80 file.txt
Explanation
- It will break lines longer than 80 characters at appropriate white spaces to make them less than 80 characters long.
- The
-sflag will collapse multiple consecutive white spaces into one, or at the end of a sentence a double space.
Come back quickly to the current directory after doing some temporary work somewhere else
bash$ pushd /some/where/else; work; cd /somewhere; work; cd /another/place; popd
Explanation
pushd,popdanddirsare bash builtins, you can read about them withhelp dirs- bash keeps a stack of "remembered" directories, and this stack can be manipulated with the
pushdandpopdbuiltins, and displayed with thedirsbuiltin pushdwill put the current directory on top of the directory stack. So, if you need to change to a different directory temporarily and you know that eventually you will want to come back to where you are, it is better to change directory withpushdinstead ofcd. While working on the temporary task you can change directories withcdseveral times, and in the end when you want to come back to where you started from, you can simply dopopd.
Export a git project to a directory
bash$ git archive master | tar x -C /path/to/dir/to/export
Explanation
The git archive command basically creates a tar file. The one-liner is to create a directory instead, without an intermediate tar file.
The tar command above will untar the output of git archive into the directory specified with the -C flag. The directory must exist before you run this command.
Delete all tables of a mysql database
bash$ mysql --defaults-file=my.cnf -e 'show tables' | while read t; do mysql --defaults-file=my.cnt -e 'drop table '$t; done
Explanation
If you have a root access to the database, a drop database + create database is easiest. This script is useful in situations where you don't have root access to the database.
First prepare a file my.cnf to store database credentials so you don't have to enter on the command line:
[client]
database=dbname
user=dbuser
password=dbpass
host=dbhost
Make sure to protect this file with chmod go-rwx.
The one-liner will execute show tables on the database to list all tables. Then the while loop reads each table name line by line and executes a drop table command.
Limitations
The above solution is lazy, because not all lines in the output of show tables are table names, so you will see errors when you run it. But hey, shell scripts are meant to be lazy!
Calculate the total disk space used by a list of files or directories
bash$ du -s file1 dir1 | awk '{sum += $1} END {print sum}'
Explanation
- This is really simple, the first column is the size of the file or the directory, which we sum up with awk and print the sum at the end.
- Use
du -skto count in kilobytes,du -smto count in megabytes (not available in some systems)
Concatenate two or more movie files into one using mencoder
bash$ mencoder cd1.avi cd2.avi -o movie.avi -ovc copy -oac copy
Explanation
- You can specify as many files as you want on the command line to process them in sequence.
-ovc copysimply means to copy the video exactly-oac copysimply means to copy the audio exactly-o movie.aviis the output file, with all the source files concatenated
Limitations
- mencoder is usually not a standard package
- mencoder may be in the same package as mplayer, or maybe not
- mencoder has binary packages for Linux, Mac and Windows
See the MPlayer homepage for more info: http://www.mplayerhq.hu/
Calculate the average execution time (of short running scripts) with awk
bash$ for i in {1..10}; do time some_script.sh; done 2>&1 | grep ^real | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
Explanation
- The for loop runs some_script.sh 10 times, measuring its execution time with
time - The stderr of the for loop is redirected to stdout, this is to capture the output of
timeso we can grep it grep ^realis to get only the lines starting with "real" in the output oftime- sed is to delete the beginning of the line up to minutes part (in the output of
time) - For each line, awk adds to the sum, so that in the end it can output the average, which is the total sum, divided by the number of input records (=
NR)
Limitations
The snippet assumes that the running time of some_script.sh is less than 1 minute, otherwise it won't work at all.
Depending on your system, the time builtin might work differently.
Another alternative is to use the time command /usr/bin/time instead of the bash builtin.
Check the performance of a script by re-running many times while measuring the running time
bash$ for i in {1..10}; do time curl http://localhost:8000 >/dev/null; done 2>&1 | grep real
Explanation
{1..10}creates a sequence from 1 to 10, for running the main script 10 times2>&1redirects stderr to stdout, this is necessary to capture the "output" of thetimebuiltin
A convenient way to re-run the previous command with sudo
bash$ sudo !!
Explanation
!! (bang bang!) is replaced with the previous command.
You can read more about it and other history expansion commands in man bash in the Event Designators section.
Put an ssh session in the background
bash$ ~^z
Explanation
- Normally,
^z(read: ctrl-z) pauses the execution of the current foreground task. That doesn't work in an ssh session, because it is intercepted by the remote shell.~^zis a special escape character for this case, to pause the ssh session and drop you back to the local shell. - For all escape characters see
~? - The
~escape character must always follow a newline to be interpreted as special. - See
man sshfor more details, search for ESCAPE CHARACTERS
Rotate a movie file with mencoder
bash$ mencoder video.avi -o rotated-right.avi -oac copy -ovc lavc -vf rotate=1
Explanation
mencoder is part of mplayer.
Other possible values of the rotate parameter:
- 0: Rotate by 90 degrees clockwise and flip (default).
- 1: Rotate by 90 degrees clockwise.
- 2: Rotate by 90 degrees counterclockwise.
- 3: Rotate by 90 degrees counterclockwise and flip.
Recursively remove all empty sub-directories from a directory tree
bash$ find . -type d | tac | xargs rmdir 2>/dev/null
Explanation
findwill output all the directoriestacreverses the ordering of the lines, so "leaf" directories come first- The reordering is important, because rmdir removes only empty directories
- We redirect error messages (about the non-empty directories) to
/dev/null
Limitations
In UNIX and BSD systems you might not have tac, you can try the less intuitive tail -r instead.
Remove all the versioned-but-empty directories from a Subversion checkout
bash$ find . -name .svn -type d | while read ss; do dir=$(dirname "$ss"); test $(ls -a "$dir" | wc -l) == 3 && echo "svn rm \"$dir\""; done
Explanation
Empty directories in version control stink. Most probably they shouldn't be there. Such directories have a single subdirectory in them named ".svn", and no other files or subdirectories.
- The "find" searches for files files named .svn that are directories
- The "while" assigns each line in the input to the variable ss
- The "dirname" gets the parent directory of a path, the quotes are necessary for paths with spaces
ls -ashould output 3 lines if the directory is in fact empty: ".", "..", and ".svn"- If the test is true and there are precisely 3 files in the directory, echo what we want to do
- If the output of the one-liner looks good, pipe it to
| shto really execute
Create a sequence of integer numbers
bash$ echo {4..-9}
Explanation
- Useful for counters. For example, to do something 10 times, you could do
for i in {1..10}; do something; done - Be careful, there cannot be spaces between the braces
- As the example shows, can count backwards too
Limitations
Does not work in /bin/sh, this is bash specific.
Redirect the output of the time builtin command
bash$ { time command; } > out.out 2> time+err.out
Explanation
timeis a bash builtin command, and redirecting its output does not work the same way as with proper executables- If you execute within braces like above, the output of time will go to stderr (standard error), so you can capture it with
2>time.out - An alternative is to use the
/usr/bin/timeexecutable, by referring to its full path. (The path may be different depending on your system.)
Copy a directory with a large number of files to another server
bash$ tar cp -C /path/to/dir . | ssh server2 'tar x -C /path/to/target'
Explanation
With a large number of files, scp or rsync can take very very long. It's much faster to tar up on one side and extract on the other. Without the -f flag tar writes output to standard output and expects input from standard input, so piping to ssh can work this way, without creating any intermediary files.
You may (or may not) gain an extra speed boost by compression, either with the z flag for tar, or with the -C flag for ssh, or with gzip pipes in the middle, like this:
tar cp -C /path/to/dir . | gzip | ssh server2 'gzip -cd | tar x -C /path/to/target'
Limitations
Depending on your system and version of tar, you may need to hyphenate the flags, for example tar -cp, and tar -x. The -C flag might also not work, but that shouldn't be too difficult to work around.
Redirect the output of multiple commands
bash$ { cmd1 ; cmd2 ; cmd3 ; } > out.out 2> err.out
Explanation
- Curly braces are very helpful for grouping several commands together
- Be careful with the syntax: 1. there must be whitespace after the opening brace 2. there must be a semicolon after the last command and before the closing brace
- Another practical use case:
test something || { echo message; exit 1; }
View a file with line numbers
bash$ grep -n ^ /path/to/file | less
Explanation
grep ^will match all lines in a filegrep -nwill prefix each line of output with the line number within its input file
Limitations
In some systems you might have to use egrep instead of grep.
Print the n-th and m-th line of a file
bash$ sed -ne '101 p' -e '106 p' /path/to/the/file
Explanation
- The above command will print the 101th and 106th lines of the specified file.
- The
-nswitch will make sed not print all lines by default. - The
-eswitch is to specify a sed command, you can use it multiple times at once.
Some sed command examples:
45 p- print line #4534,55 p- print lines #34-#5599,$ p- print lines #99-end of the file
Repeat the previous command but with a string replacement
bash$ ^geomtry^geometry
Explanation
This can be very useful for example after a mistyped command like this:
convert -crop 745x845+0+150 my_logo.png -geomtry 400x my_logo2.png
^geomtry^geometry
"-geomtry" should have been "-geometry", the one-liner above will re-run the command with a replacement that fixes the typo.
Rename all files in the current directory by capitalizing the first letter of every word in the filenames
bash$ ls | perl -ne 'chomp; $f=$_; tr/A-Z/a-z/; s/(?<![.'"'"'])\b\w/\u$&/g; print qq{mv "$f" "$_"\n}'
Explanation
- When you pipe something to
perl -ne, each input line is substituted into the$_variable. Thechomp,tr///,s///perl functions in the above command all operate on the$_variable by default. - The
tr/A-Z/a-z/will convert all letters to lowercase. - The regular expression pattern
(?<![.'])\b\wmatches any word character that follows a non-word character except a dot or a single quote. - The messy-looking
'"'"'in the middle of the regex pattern is not a typo, but necessary for inserting a single quote into the pattern. (The first single quote closes the single quote that started the perl command, followed by a single quote enclosed within double quotes, followed by another single quote to continue the perl command.) We could have used double quotes to enclose the perl command, but then we would have to escape all the dollar signs which would make everything less readable. - In the replacement string
$&is the letter that was matched, and by putting\uin front it will be converted to uppercase. qq{}in perl works like double quotes, and can make things easier to read, like in this case above when we want to include double quotes within the string to be quoted.- After the conversions we print a correctly escaped mv command. Pipe this to bash to really execute the rename with
| sh.
Limitations
The above command will not work for files with double quotes in the name, and possibly other corner cases.
Do not save command history of current bash session
bash$ HISTFILE=
Explanation
The command history of the current bash session is saved to $HISTFILE when you exit the shell. If this variable is blank, the command history will not be saved.
Use rsync instead of cp to get a progress indicator when copying large files
bash$ rsync --progress largefile.gz somewhere/else/
Explanation
Although rsync is famous for synchronizing files across machines, it also works locally on the same machine. And although the cp command doesn't have progress indicator, which can be annoying when copying large files, but rsync does have it, so there you go.
Limitations
When copying directories be careful that the meaning of a trailing slash when specifying directories can be slightly different from cp.
Create and restore backups using cpio
bash$ find . -xdev -print0 | cpio -oa0V | gzip > path_to_save.cpio.gz
Explanation
To restore:
gzip -cd path_to_save.cpio.gz | cpio -imV
Why not use tar instead? cpio is slightly more accurate!
find . -xdev -print0finds all files and directories without crossing over to other partitions and prints a null delimited list of filenamescpio -oa0Vtakes the list of files to archive from stdin and creates an archive file preserving timestamps and permissionscpio -imVextracts the files and directories from stdin while preserving timestamps and permissions
Get the available space on a partition as a single numeric value
bash$ df /path/to/dir | sed -ne 2p | awk '{print $4}'
Explanation
sed -ne 2pprints the 2nd lineawk '{print $4}'prints the 4th column
Limitations
The output of the df command might be different depending on the system, and the available space might not be the 4th column. Make the necessary adjustments depending on your system.
Schedule a one-time task using "at" command and intuitive date specifications
bash$ at now + 30 minutes
Explanation
- The example will run something 30 minutes from now.
- Another example:
at 0815 wed-- run something at 8:15am on the next Wednesday. - With
atqyou can see the list of scheduled jobs, this is good to confirm that you specified the date correctly and the job will run when you want. - With
atrmyou can cancel scheduled jobs, using the job id as parameter, which you can find in theatqoutput.
Remove spaces recursively from all subdirectories of a directory
bash$ find /path/to/dir -type d | tac | while read LINE; do target=$(dirname "$LINE")/$(basename "$LINE" | tr -d ' '); echo mv "$LINE" "$target"; done
Explanation
find path_to_dir -type dfinds all the subdirectoriestacreverses the order. This is important to make "leaf" directories come first!target=...stuff constructs the new name, removing spaces from the leaf component and keeping everything before that the sameecho mv ...for safety you should run with "echo" first, if the output looks good then remove the "echo" to really perform the rename
Limitations
In UNIX or BSD there is no tac. There you can use tail -r instead.
Replace a regexp pattern in many files at once
bash$ vi +'bufdo %s/pattern/replacement/g | update' +q $(grep -rl pattern /path/to/dir)
Explanation
- The inner grep will search recursively in specified directory and print the filenames that contain the pattern.
- All files will be opened in vi, one buffer per file.
- The arguments starting with + will be executed as vi commands:
bufdo %s/pattern/replacement/g | update= perform the pattern substitution in all files and save the changesq= exit vi
Limitations
The :bufdo command might not be there in old versions of vim.
The first command you should run right after you login to a remote server ;-)
bash$ screen
Explanation
With screen you can have multiple shells in the same window. You don't need to open new windows for a second connection to the same remote server, you can simply press C-a c inside the screen session. And if your computer crashes, you screen session on the remote server survives, you can re-attach to a previous screen session with screen -R.
Find video files cached by the flash plugin in browsers
bash$ file /proc/*/fd/* 2>/dev/null | grep Flash | cut -f1 -d:
Explanation
Recent versions of the flash plugin hide the temporary file by marking it deleted. Practically the video stream is downloaded to a "deleted file". However, even when a file is deleted, if the file is opened by a process then you can find its file descriptor and consequently the file contents.
This simple script prints out the file descriptors of opened Flash videos:
file /proc/*/fd/* 2>/dev/null | grep Flash | cut -f1 -d:
And, you probably want to create a regular file from the file descriptor, for example:
cp $(file /proc/*/fd/* 2>/dev/null | grep Flash | cut -f1 -d: | head -n 1) video.avi
Otherwise the file descriptor is not very convenient (remember, it's a deleted file!)
The method should work regardless of your browser.
Force the preferred language when downloading a web page with wget
bash$ wget -–header='Accept-Language: en-us' http://www.timeanddate.com/calendar/index.html?year=2008&country=26 -O calendar.html
Explanation
When downloading web pages with wget, some websites try to be smart and detect your preferred language based on geographical location of your IP address. This can be a problem if for example you are in Japan but you want to download a page in English.
Burn the contents of a directory to dvd without needing a gui application
bash$ growisofs -dvd-compat -Z /dev/scd0 -R -J -pad /path/to/dir
Explanation
Useful if you have a directory full of data to burn to DVD without using a GUI.
The growisofs tool is in the "dvd+rw-tools" package in Ubuntu, install it with:
sudo apt-get install dvd+rw-tools
Convert all flac files in the current directory to mp3 format using "lame"
bash$ for i in *.flac; do flac -c -d "$i" | lame -m j -b 192 -s 44.1 - "${i%.flac}.mp3"; done
Explanation
Halt the system in Linux without the halt command or gui
bash$ echo o > /proc/sysrq-trigger
Explanation
- First you need to enable the sysrq interface with:
echo 1 > /proc/sys/kernel/sysrq echo o > /proc/sysrq-triggerhaltsecho b > /proc/sysrq-triggerreboots
Create an encrypted tar file with openssl
bash$ tar c paths_to_files_and_dirs | gzip -c | openssl des3 > encrypted.tar.gz
Explanation
Decrypt with: openssl des3 -d < encrypted.tar.gz | tar zx
Make another user superuser in Ubuntu
bash$ for i in $(grep :boss /etc/group | cut -f1 -d:); do adduser wife $i; done
Explanation
In Ubuntu the first user (created during installation) has special privileges. The privileges come from the fact that the user was automatically added to various system groups. To make another user have the same privileges, all you need to do is add the user to the same groups.
grep :boss /etc/groupgets the group records where the userbossis the first member.cut -f1 -d:gets the first column, where ":" is the column separator.for i in ...; do ... ; donefor each group it adds the user to the group.
Change the label of a USB drive in Linux without a gui
bash$ sudo mlabel -i /dev/sdd1 ::NewLabel
Explanation
Replace /dev/sdd1 with whatever your USB stick is mounted on.
Mirror from one Subversion repository to another Subversion repository
bash$ bzr co https://repo1/proj1/trunk proj1 && cd proj1 && bzr push https://repo2/vendor/proj1/trunk
Explanation
- The commit history in repo1 will be copied to repo2.
- The temporary Bazaar repository (proj1) will have the full history of changes.
- The command above initializes the mirror. To update the mirror, run this script, you can schedule it to run periodically to keep the mirror up to date:
cd proj1 && bzr up && bzr push
Limitations
- The author information will get lost in the process.
An elegant way to rename all files in a directory to lowercase names
bash$ paste <(ls) <(ls | tr A-Z a-z) | while read OLD NEW; do echo mv -v $OLD $NEW; done
Explanation
<(cmd)is the filename of a named pipe (FIFO), where the named pipe is filled by the output ofcmdpasteputs together the named pipes to form two columns: first column with the original filenames, second column with the lowercased filenames... | tr abc ABCtransforms stdin by replacing any characters that appear in the first set of letters to the second set of letterswhile read old new; do ...; donefor each line it reads the first column into$oldand the second column into$new
Limitations
- Won't work if there are spaces in a filename.
Find Flash videos stored by browsers on a Mac
bash$ find /private/ 2>/dev/null | grep /Flash
Explanation
When you watch a flash video like youtube in a browser, the video file is saved on your harddisk at a temporary location. And, if you watch a video and then another video in the same window, the first one will be deleted.
Limitations
- Might not work with all browsers.
- Does not work with all websites (for example IMDB).
- Does not work with an anonymous window in Chrome.
Favourite one-liners
Not implemented yet.
One-liners voted on
Not implemented yet.