Using the xargs command on Linux to simplify your work

The xargs command on Linux can make it easier to build and execute commands. If you want to run the same command for a group of files or users, xargs can often make that process easier. Here's a very simple example of xargs that creates or updates the update time on some files.

$ echo file1 file2 file3 | xargs touch
$ ls -l
total 0
-rw-r--r--. 1 shs shs 0 Oct 15 12:41 file1
-rw-r--r--. 1 shs shs 0 Oct 15 12:41 file2
-rw-r--r--. 1 shs shs 0 Oct 15 12:41 file3

The command below is similar, but creates a file with blanks in its name because the -d specifies the input termination character.

$ echo 'my new file' | xargs -d '\n' touch
$ ls -l
total 0
-rw-r--r--. 1 shs shs 0 Oct 15 12:41  file1
-rw-r--r--. 1 shs shs 0 Oct 15 12:41  file2
-rw-r--r--. 1 shs shs 0 Oct 15 12:41  file3
-rw-r--r--. 1 shs shs 0 Oct 15 12:57 'my new file'

On the other hand, commands like those shown above create empty files or update the date/time on the files, but each runs a single command (i.e., "touch file1 file2 file3" and "touch 'my new file'") that's much simpler than the one shown. Added to the end of a command that selects or finds files by some criteria, using xargs can be considerably more useful. Here's an example that changes permissions on all png files within the images directory:

$ find images -name "*.png" -type f | xargs chmod 640

To view the command that is run by xargs, add the -t option:

$ echo file1 file2 file3 | xargs -t touch
touch file1 file2 file3          <== command that is run

$ find images -name "*.png" -type f | xargs -t chmod 640 chmod 640 images/Penguin_Simpson.png images/Penguin_joined-1.png images/Penguin_purple.png images/joined-1.png images/Penguin_10quality.png images/joined-0.png images/penguin.png images/Penguin_50quality.png images/penguin0.png images/appended.png images/45.png images/Penguin_flipped.png images/Penguin_blurred.png images/Mailing_label_2.png images/Penguin_Simpson_2.png images/Penguin_joined-0.png images/outfile.png images/Penguin_45.png images/penguin4.png images/Mailing_label.png images/arrow.png

In the example below, we use find to locate files that haven't been updated in more than four weeks and xargs to remove them.

$ find . -mtime +28 | xargs rm

This is a command for finding and removing empty files starting in the current directory:

$ find . -size 0 | xargs rm

Doing the same thing when there may be blanks in some of the file names could be done with a command like this:

$ find . -size 0 | xargs -I{} rm -v {}
removed './empty'
removed './my empty file'

The xargs command is frequently used with find to locate and deal with files according to many different criteria such as age, file type and permissions.

In the example below, we're looking at files in the current directory. The ls command uses -Srp to ensure that directories are listed with a slash at the end. The grep command then removes those directories from the list that is passed to xargs. The xargs command then uses X (this could be any word or character) as a loop variable and then uses wc -c to count the characters in each file.

$ ls -Srp | grep -v '/$' | xargs -I X wc -c X
64 file3
77 my new file
106 file2
361 file1

Note that the loop character needs to be included in two positions in the command.

To view the most recent three logins for each currently logged-in user, you could use a command like this:

$ who | awk '{print $1}' | xargs -I x last -3 x
shs      pts/0        192.168.0.24     Fri Oct 15 12:35   still logged in
shs      pts/0        192.168.0.9      Wed Oct 13 16:40 - 17:20  (00:39)
shs      pts/0        192.168.0.9      Wed Oct 13 15:56 - 16:26  (00:30)

wtmp begins Fri Mar 12 12:50:16 2021
nemo     pts/1        192.168.0.24     Fri Oct 15 13:13   still logged in
nemo     pts/1        192.168.0.10     Tue Sep  7 12:23 - 14:13  (01:50)
nemo     pts/1        192.168.0.10     Sun Aug 22 11:10 - 12:01  (00:51)

wtmp begins Fri Mar 12 12:50:16 2021

The looping is needed to make the command run separately for each user.

One of the key things to keep in mind is that any command you use with xargs will add the text you pass it to the end of the command. You cannot use a command like the one shown below and expect it to display the first three months of 2022 because the cal command expects the year to be the final argument:

$ echo 1 2 3 | xargs cal 2022
cal: bad usage
Try 'cal --help' for more information.

Try the same command without 2022 at the end and you'll only learn that February 1st in the year 3 was a Thursday.

The xargs command can be very helpful in providing an easy way to run commands, especially when combined with commands that locate the files or specify the users that you need to check.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Related:

Copyright © 2021 IDG Communications, Inc.

SD-WAN buyers guide: Key questions to ask vendors (and yourself)