View previous topic :: View next topic |
Author |
Message |
wjholden l33t
Joined: 01 Mar 2004 Posts: 826 Location: Augusta, GA
|
Posted: Fri Feb 15, 2013 6:45 pm Post subject: [Improvement] find /lib/modules/<kernel version>/ -typ |
|
|
The Gentoo Handbook has this awesome command for helping you locate the kernel modules you've installed: Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | less | Pretty much every time I upgrade my kernel I end up opening up the Handbook for this command, just so I don't miss any new modules. But the list it gives you is ugly, with absolute paths and .ko filename extensions. How can you make this a little easier? With a bit of logic. Behold: Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | sed "s/.ko//" | sed 's/^.*\///' | This gives you a nice list of modules your kernel version can use.
How does it work? The first sed command has three parts in it's "s/.ko//"
s - substitute the text between the first set of forward slashes for the text in the second set of forward slashes.
/.ko/ - look for lines that contain this text.
// - replace .ko with the text here, in this case replace .ko with nothing.
That gets us a list of absolute pathnames without filename extensions. The second sed command uses two special characters to remove the directory names with sed 's/^.*\///'.
/^.*\// - "^" means start at the beginning of the line. "." matches any character, and "*" means patch the preceding (any) character zero or more times. The "/" we are looking for (the last "/" in the line) is escaped with "\" because "/" has special meaning to the sed program and most GNU-style regular expression handling.
It appears that the default behaviour of sed searches right to left; I'm sure there is a way to change that, but in this case it works.
Now you have a list of filenames, but they are all on one line. I couldn't think of an existing Linux command that would combine these into a single line, so I wrote one in Perl: Code: | #!/usr/bin/perl -w
my @strings;
while ($in = <>)
{
push (@strings, $in);
}
foreach $s (@strings)
{
chomp($s);
print $s . " ";
}
print "\n"; | Simply save to a .pl file and chmod a+x. I copied this program to /usr/local/bin/oneline.pl. Now you have a quick an easy method to grab all those modules to /etc/conf.d/modules. Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | sed "s/.ko//" | sed 's/^.*\///' | oneline.pl |
|
|
Back to top |
|
|
khayyam Watchman
Joined: 07 Jun 2012 Posts: 6227 Location: Room 101
|
Posted: Sun Feb 17, 2013 10:36 am Post subject: Re: [Improvement] find /lib/modules/<kernel version>/ |
|
|
wjholden wrote: | Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | sed "s/.ko//" | sed 's/^.*\///' |
|
wjholden ... you might save the additional pipe/sed by using awk for the pattern/field.
Code: | % find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | awk -F"/" '{gsub(/.(ko|o)$/,""); print $NF}' |
Note that the -iname '*.o' would either be unnecessary, or would need to be accounted for in the substitution.
wjholden wrote: | Now you have a list of filenames, but they are all on one line. I couldn't think of an existing Linux command that would combine these into a single line, so I wrote one in Perl
[...]
Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | sed "s/.ko//" | sed 's/^.*\///' | oneline.pl |
|
You can use a 'printf' ...
Code: | % find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | awk -F"/" '{gsub(/.(ko|o)$/,""); printf $NF" "}' |
best ... khay |
|
Back to top |
|
|
Hu Moderator
Joined: 06 Mar 2007 Posts: 21586
|
Posted: Sun Feb 17, 2013 5:54 pm Post subject: Re: [Improvement] find /lib/modules/<kernel version>/ |
|
|
I find it vaguely unsettling that a Cisco-certified individual would take such a long way to achieve such a simple result, especially since you then go on to explain sed regular expressions in detail. Even setting aside the nice rewrite that khayyam gave you, there are better ways to do what you want.
wjholden wrote: | Behold: Code: | find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | sed "s/.ko//" | sed 's/^.*\///' |
| Why use two calls to sed? You can pass two (or more) expressions to a single sed, if you name each of them as explicit expressions: sed -e "s/.ko//" -e 's/^.*\///'.
Why use -iname? Kernel module names are always .ko, never .kO, .Ko, or .KO.
wjholden wrote: | Now you have a list of filenames, but they are all on one line. I couldn't think of an existing Linux command that would combine these into a single line | According to the documentation, xargs has an implicit command of /bin/echo when invoked without an explicit command. You could also use xargs printf '%s ', though that is somewhat longer. For some unusual inputs, you may need to use xargs -d'\n'.
wjholden wrote: | so I wrote one in Perl: | You missed both use strict; and use warnings FATAL => qw(all);. You enabled warnings, which is good, but you did not make them fatal.
wjholden wrote: | Code: |
my @strings;
while ($in = <>)
{
push (@strings, $in);
}
foreach $s (@strings)
{
chomp($s);
print $s . " ";
} |
| Why build a temporary array just to print it back? Chomp the lines as you get them, and print them on the spot. Code: | while(<>){chomp;print "$_ ";} |
You could avoid one sed transform and the use of the oneline.pl script with a good use of -printf: Code: | find /lib/modules/$(uname -r) -type f -name '*.ko' -printf '%f ' |
[Edit: my initial advice used the wrong format specifier in the find -printf that I recommended. The correct specifier for this usage is %f, not %P as I originally stated.]
Last edited by Hu on Sun Feb 17, 2013 7:26 pm; edited 1 time in total |
|
Back to top |
|
|
wjholden l33t
Joined: 01 Mar 2004 Posts: 826 Location: Augusta, GA
|
Posted: Sun Feb 17, 2013 6:13 pm Post subject: |
|
|
Tough crowd
Great ideas and advice, both of you. Thanks! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|