0

What is the meaning of this command: ls -lt | grep - | head -1 | awk '{print $9}' | xargs rm.

I know the individual meaning of these commands but what happens when we join them by pipe?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
devashish-patel
  • 663
  • 1
  • 7
  • 15
  • Duplicate - https://stackoverflow.com/questions/9834086/what-is-a-simple-explanation-for-how-pipes-work-in-bash – battlmonstr Mar 06 '19 at 23:21

1 Answers1

1

A simple way to see what long pipelines do is run them one piece at a time. Run ls -lt, then ls -lt | grep -, then ls -lt | grep - | head -1, etc. See what the intermediate output of each command is so you know what's being fed into the next.

$ cd /usr
$ ls -lt
total 156
drwxr-xr-x  11 root root  4096 Mar  6 06:35 src/
drwxr-xr-x   2 root root 90112 Mar  5 06:27 bin/
drwxr-xr-x   2 root root 12288 Mar  5 06:27 sbin/
drwxr-xr-x 155 root root  4096 Mar  5 06:27 lib/
drwxr-xr-x  50 root root 20480 Feb 20 18:11 include/
drwxr-xr-x 330 root root 12288 Feb 18 16:58 share/
drwxr-xr-x   2 root root  4096 Oct 19 13:51 games/
drwxr-xr-x   3 root root  4096 Jul 19  2016 locale/
drwxr-xr-x  10 root root  4096 Jul 19  2016 local/

File listing with each entry on its own line along with permissions, size, and other information. Looking at man ls I see that the -t flag means the files are sorted by modification time, newest to oldest.

$ ls -lt | grep -
drwxr-xr-x  11 root root  4096 Mar  6 06:35 src/
drwxr-xr-x   2 root root 90112 Mar  5 06:27 bin/
drwxr-xr-x   2 root root 12288 Mar  5 06:27 sbin/
drwxr-xr-x 155 root root  4096 Mar  5 06:27 lib/
drwxr-xr-x  50 root root 20480 Feb 20 18:11 include/
drwxr-xr-x 330 root root 12288 Feb 18 16:58 share/
drwxr-xr-x   2 root root  4096 Oct 19 13:51 games/
drwxr-xr-x   3 root root  4096 Jul 19  2016 locale/
drwxr-xr-x  10 root root  4096 Jul 19  2016 local/

Appears to remove the "total 156" line. (If that's the goal it's a rather poor way to do it. There's no guarantee that every line has a dash in it, which is what grep - is looking for. A file with full rwxrwxrwx permissions wouldn't have a dash in the line.)

$ ls -lt | grep - | head -1
drwxr-xr-x  11 root root  4096 Mar  6 06:35 src/

Gets the first line of the previous grep results.

$ ls -lt | grep - | head -1 | awk '{print $9}'
src/

Prints the ninth column, the file name.

Careful: At this point you could tack on | xargs rm, but that rm looks dangerous. Let's not, eh? Instead of running it to see what happens, I'd try man xargs to see what xargs rm does. Or google "xargs rm": aha, that tells me that it'll delete the files being passed in. Good to know—I think I'll pass.

Put all the pieces together and you might describe the overall result as "list files in reverse chronological order, find the first, and delete it". Or in other words, delete the newest file. That's what the whole thing does.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578