What's this?

commandlinefu.com is the place to record those command-line gems that you return to again and again.

Delete that bloated snippets file you've been using and share your personal repository with the world. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

Get involved!

You can sign-in using OpenID credentials, or register a traditional username and password.

First-time OpenID users will be automatically assigned a username which can be changed after signing in.

Universal configuration monitoring and system of record for IT.

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.

» http://twitter.com/commandlinefu
» http://twitter.com/commandlinefu3
» http://twitter.com/commandlinefu10

Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for:



May 19, 2015 - A Look At The New Commandlinefu
I've put together a short writeup on what kind of newness you can expect from the next iteration of clfu. Check it out here.
March 2, 2015 - New Management
I'm Jon, I'll be maintaining and improving clfu. Thanks to David for building such a great resource!

Top Tags



Psst. Open beta.

Wow, didn't really expect you to read this far down. The latest iteration of the site is in open beta. It's a gentle open beta-- not in prime-time just yet. It's being hosted over at UpGuard (link) and you are more than welcome to give it a shot. Couple things:

  • » The open beta is running a copy of the database that will not carry over to the final version. Don't post anything you don't mind losing.
  • » If you wish to use your user account, you will probably need to reset your password.
Your feedback is appreciated via the form on the beta page. Thanks! -Jon & CLFU Team

Recursively scan directories for mp3s and pass them to mplayer

Terminal - Recursively scan directories for mp3s and pass them to mplayer
rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing
2010-03-23 21:33:44
User: hhanff
Functions: find grep rm
Recursively scan directories for mp3s and pass them to mplayer

The command first deletes any old playlist calles playlist.tmp under /tmp. After that it recursively searches all direcotries under ~/mp3 and stores the result in /tmp/playlist.tmp. After havin created the playlist, the command will execute mplayer which will shuffle through the playlist.

This command is aliased to

m is aliased to `rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing'

in my ~/.bashrc.


There is 1 alternative - vote for the best!

Terminal - Alternatives
$ find . -iname *.mp3 | while read line ; do ln -s "$line" $(echo -e "$line" | openssl md5).mp3 ; done ; mpg123 *.mp3

Know a better way?

If you can do better, submit your command here.

What others think

By the way: Can anybody figure out how to do the same thing without creating a temporary playlist? I tried to pass the results of find to mplayer via xargs, but then the keyboard controls of mplayer won't function any more....

Comment by hhanff 335 weeks and 6 days ago

What about 'find ~/mp3 -iname *.mp3 -exec mplayer -shuffle -loop {} \;' ? I am not at a *nix machine right now, so I can't test it, but something like this would not require a playlist.

Comment by philthomson 335 weeks and 6 days ago

The '-iname' option on find will help if you have mp3's where the extension is .MP3 as opposed to .mp3

Comment by philthomson 335 weeks and 6 days ago

My suggestion doesn't work, but I did google the problem with mplayer and found this: 'http://www.linuxquestions.org/questions/linux-software-2/xargs-mplayer-loses-key-controls-635170/' The suggested workaround only works for files with no spaces in them, but I'm sure there is some way to do it for all kinds of file names.

Comment by philthomson 335 weeks and 6 days ago

"find blablabla | mplayer -playlist -" will build a playlist from stdin. Also, you should write "\*.mp3" instead of simply "*.mp3", otherwise your shell will expand * before it gets to find, and find will get a list of *-mp3's in cwd

Comment by benjamin 335 weeks and 6 days ago

@philtomson: I found the same page yesterday but had not idea how to make it work...

@ benjamin:

find ~/mp3 -name "*.mp3" | mplayer -playlist - -shuffle -loop 0

does not allow to control mplayer with keyboard any more.... e.g. "next song" by hitting return... :/

Here's a better version which filters out all "audio books":

rm -rf /tmp/playlist.tmp && find ~/mp3 -name *.mp3 -not -name 'H?rb?cher' > /tmp/playlist.tmp && mplayer -playlist /tmp/playlist.tmp -shuffle -loop 0 | grep Playing
Comment by hhanff 335 weeks and 6 days ago

Okay, this works:

for i in "$(find . -type d)";do d=( $i/*.mp3 ); files=( "${files[@]}" "${d[@]}" );done; mplayer -shuffle -loop 0 "${files[@]}"

ugly as hell though :D

Comment by benjamin 335 weeks and 5 days ago

Sin!!! That's a big one...

Comment by hhanff 335 weeks and 5 days ago

old topic, but i use this for the new car system (2014) so i can select the tracks i want to listen to in the new car from a vast list. ( 8G card and system requires play lists.) I know its not brilliant but does a job and may be a starting point for others.


use strict;

use warnings;

#use File::Spec::Functions qw'no_upwards';

my $PLHeader="\n\n \n \n \n\n \n \n \n \n \n \n Others\n \n \n \n";

my $PLData="

my $PLTail=" \n \n";

my $PLID="";

my $InitDir;

my $FileAll;

my $FileRoot;

my %OpenFile;

if ($ARGV[0] eq ""){






open(PLALL, "> $FileAll") or die "Unable to open _all.wpl";

print PLALL $PLHeader;


#open(PLROOT, "> $FileRoot") or die "Unable to open all.pl";

#print PLROOT $PLHeader;

sub Read_Dir {

my $entry;

my $dir = $_[0];

my $prevpath = $_[1];

my $DirLevel = $_[2];

my $DirPL;

my $PLOpen="N";

my $PLName;

my @Files;

my @Dirs;

my $wDir;

print "\$dir=$dir, \$prevpath=$prevpath, \$DirLevel=$DirLevel\n";

if ( $prevpath eq "" ) {





opendir(DIRID, $wDir) || die "can't opendir $wDir $!";

print "\$InitDir=$InitDir, \$dir=$dir, \$wDir=$wDir\n";

@Files = grep { ( /\.mp3$/ || /\.m4a$/ || /\.wma$/ || /\.aac$/ || /\.aif$/ || /\.flac$/ ) && -f "$wDir/$_" } readdir DIRID;

rewinddir( DIRID );

@Dirs = grep { !/^\./ && -d "$wDir/$_" } readdir DIRID;

close DIRID;

# print "Files ---------------->\n";

# print join(",\n",@Files);

# print "Dirs ---------------->\n";

# print join(",\n",@Dirs);

#exit 0;

print "Process Files array for $wDir\n";

foreach $entry (@Files) {

print "working on File - $entry\n";

# print "$PLOpen ,$dir, $InitDir \n";

#next if -l "$dir/$entry"; # symbolic link

if ($PLOpen eq "N" ){

print "open playlist /n";

if ($dir eq $InitDir) {


# print "PLName = $PLName\n";




open(PLDIR, "> $InitDir/$PLName") or die "Can not open $PLName\n";

print "Openned $InitDir/$PLName \n";

$PLOpen = "Y";

print PLDIR $PLHeader;



# sort $PLNAME - not correct path to file.


if ( $dir eq $InitDir ) {

print PLALL $PLData."/$entry\"/>\n";

print PLDIR $PLData."/$entry\"/>\n";


print PLALL $PLData."/$dir/$entry\"/>\n";

print PLDIR $PLData."/$dir/$entry\"/>\n";

# print "F - $entry \n";



print PLDIR $PLTail;

close PLDIR;

print "\n\nend of files-------------------

print "$dir dir array count = $#Dirs\n";


foreach $entry (@Dirs) {

next if $entry eq "." or $entry eq ".."; # system entries

next if "$entry" eq "System Volume Information";

next if "$entry" eq "IndexerVolumeGuid";

print "D - $dir/$entry \n";

print "calling Read_Dir(\$entry,\$dir,\$DirLevel) - Read_Dir($entry,$dir,$DirLevel)\n";

Read_Dir($entry,$dir,$DirLevel); # recurse



Read_Dir($InitDir,"",0); # our top-level directory

print PLALL $PLTail;

#print PLROOT $PLTail;

close PLALL;

#close PLROOT;

exit 0;

Comment by gittingr 92 weeks and 2 days ago

Your point of view

You must be signed in to comment.