Sunday, 17 March 2013

Skip the Script and Try the Apply Command

The apply command helps you process parameters in a single line


In this article, I’ll present a nifty little trick for running a command on a set of parameters. This trick uses the AIXapply command. Apply can be easier to use than more elaborate tools such as xargs, awk, or perl, so it's a helpful command to have up your sleeve. As you'll see, you can write a one-liner using apply and save yourself from creating a more elaborate loop or writing a script.
You can use apply to create simple reports; for example, displaying one of the attributes for a set of disks. First, I'll show how you do that using the more traditional for loop, then I’ll show you how it can be done using apply.

Looping the Loop

Suppose you have an I/O bottleneck and want to get the queue_depth attribute for all your physical volumes. You could run lsattr on each physical volume, with the disk name and the queue depth attribute indicated by the -a flag:
lsattr -El hdisk0 -a queue_depth
queue_depth 3 Queue DEPTH True
To do that for several disks (physical volumes), you can use a loop. To run the lsattr for hdisk0 through hdisk2:
for i in hdisk0 hdisk1 hdisk2
do
    lsattr -El $i -a queue_depth
done
queue_depth 3 Queue DEPTH True
queue_depth 20 Queue DEPTH True
queue_depth 20 Queue DEPTH True
You could make that a tad cleaner by placing just the disk numbers in the top of the forloop:
for i in 0 1 2
do
    lsattr -El hdisk${i} -a queue_depth
done
queue_depth 3 Queue DEPTH True
queue_depth 20 Queue DEPTH True
queue_depth 20 Queue DEPTH True
This requires you to type in the numbers of each physical volume (hdisk) you're checking. That gets a bit cumbersome if you have a large number of physical volumes, especially if they aren’t numbered sequentially. So, rather than hard-coding the physical volumes or storing their names in a file, it would be better to get a list of the physical volumes using the lsdev command. That way, you're working off an up-to-date list of physical volumes each time you run the command. Better still, the exact same command would work on a different AIX logical partition, even if that partition had a completely different set of hdisk numbers.
You can get the list of disks using the lsdev command:
lsdev -c disk -F name
hdisk0
hdisk1
hdisk2
You could then include that command in your original loop:
for i in $(lsdev -c disk -F name)
do
     lsattr -El $i -a queue_depth
done

Apply Now

You can do something similar using the apply command. The syntax for apply is surprisingly simple:
apply CommandString Parameter
Or, if you prefer, “apply this command to these parameters.”
Here's a simple example: Suppose you want to display a list of words using the echocommand, with one word on each line. You can run the following:
apply "echo" one two three four five six seven eight nine
one
two
three
four
five
six
seven
eight
nine
This example had one command (echo) and nine parameters, and the echo command ran for each parameter. But suppose you want the apply command to run on every third parameter. You would do that by inserting %3 into your command string. Here, I'll echoevery third parameter:
apply "echo %3" one two three four five six seven eight nine
three
six
nine

Apply to All Disks

Now that you've seen the apply command in action, it's very easy to get it working to display the queue_depth disk attribute for all disks. You can run the command lsattr on every disk that’s listed when you run lsdev. Here's how that looks:
apply "lsattr -El %1 -a queue_depth" $(lsdev -c disk -F name)
queue_depth 3 Queue DEPTH True
queue_depth 20 Queue DEPTH True
queue_depth 20 Queue DEPTH True
Let's enhance it a little. As you saw before, you can display every parameter by running the echo command:
apply "echo %1" $(lsdev -c disk -F name)
hdisk0
hdisk1
hdisk2

Putting it All Together

Here's how to combine the two commands. First, run the echo command to display the disk name. If the echo command is successful (indicated by a double ampersand, &&), run the lsattr command:
apply "echo %1 && lsattr -El %1 -a queue_depth" $(lsdev -c disk -F name)
hdisk0
queue_depth 3 Queue DEPTH True
hdisk1
queue_depth 20 Queue DEPTH True
hdisk2
queue_depth 20 Queue DEPTH True

Simple Math

How about some basic math? The following is the syntax for performing multiplication using the expr command. The multiplication is indicated by the asterisk (*) and needs to be escaped by a backslash.
expr 100 \* 2
200
So, suppose you had a set of numbers. You could multiply each number by two usingapply and expr:
apply "expr %1 \* 2" 1 2 3 4 5 6
2
4
6
8
10
12

Wider Application

Once you think about it, I believe you'll find that there are many uses for apply. For example, instead of using apply to run a single command against a set of parameters, you could use it to run a script. Apply is both simple and powerful. If you're not familiar withapply, avoid using it to make any changes; instead, use it initially just to list details (e.g., list attributes of devices, volume groups, file systems, or users). I think you’ll find that it's a pretty good tool to have in your systems admin arsenal.

No comments:

Post a Comment