How to determine if a specific module is loaded in linux kernel - unix

I am just curious is there any way to determine if a particular module is loaded/installed.
$ lsmod lists all modules (device driver loaded).
Is there any way to check or a command that returns true/false boolean output if a module name is polled. For eg. if keyboard.o exists return true else false. I need this tip to complete my driver auto refresh program.
PS: tried modinfo. I am using busybox client in my test DUT so can you give some alternatives other than modinfo?

The modinfo module method does not work well for me. I prefer this method that is similar to the alternative method proposed:
#!/bin/sh
MODULE="$1"
if lsmod | grep -wq "$MODULE"; then
echo "$MODULE is loaded!"
exit 0
else
echo "$MODULE is not loaded!"
exit 1
fi

not sure if modinfo modname and checking $? will work for you, just a suggestion.
/tmp$ sudo modinfo e1000
/tmp$ echo $?
0
/tmp$ sudo modinfo keyboard
ERROR: modinfo: could not find module keyboard
/tmp$ echo $?
1
alternatively you also grep /proc/modules

The --first-time flag causes modprobe to fail if the module is already loaded. That in conjunction with the --dry-run (or the shorthand -n) flag makes a nice test:
modprobe -n --first-time $MODULE && echo "Not loaded" || echo "Loaded"
Edit 1: As #Nobody pointed out this also prints Loaded if the module does not exist. We can fix this by combining it with modinfo:
modinfo $MODULE >/dev/null 2>/dev/null &&
! modprobe -n --first-time $MODULE 2>/dev/null &&
echo "Loaded" || echo "Not loaded"
Edit 2: On some systems modprobe lives in /usr/sbin, which is not in the $PATH unless you are root. In that case you have to substitute modprobe for /usr/sbin/modprobe in the above.

I wrote this:
MODULE=snd_aloop # for example
test -n "$(grep -e "^$MODULE " /proc/modules)" && echo "Loaded" || echo "Not loaded"
It checks in /proc/modules. If the module is mentioned there, it's assumed to be loaded, otherwise not.
The others seemed too long to me (the other short one requires root, this does not). Of course it's just written out what was already mentioned as "alternatives".
Caution: modprobe accepts some variants of module names other than the primary listed in /proc/modules. For example loading snd-aloop works, but the module is named snd_aloop and is listed as such in /proc/modules and when using rmmod that's also the only name that will work.

My short way to find if a given module is actually loaded:
cat /proc/modules | grep -c nfnetlink
which outputs
2
That 2 (TWO) means the module is LOADED. The actual output without -c shows all loaded modules with MODULENAME - -c counts the lines that contain MODULENAME. So if you have 0 (ZERO) lines as output then the module is not loaded

The better idea is to create a bash function:
#!/bin/sh
function moduleExist(){
MODULE="$1"
if lsmod | grep "$MODULE" &> /dev/null ; then
return 0
else
return 1
fi
}
if moduleExist "module name"; then
#do somthing
fi

!/bin/sh
# Module
MODULE="scsi_dh_rdac"
#Variables check if module loaded or not
MODEXIST=/sbin/lsmod | grep "$MODULE"
if [ -z "$MODEXIST" ]; then
/sbin/modprobe "$MODULE" >/dev/null 2>&1
fi

module list
Returns:
Currently Loaded Modulefiles:
1) /coverm/0.3.0 2) /parallel/20180222

grep -wEq "^${module%.o}" /proc/modules
returns true (e.g. can be used in an if) whether you ask for keyboard or keyboard.o

grep -q $pattern against lsmod or /proc/modules, which are available on most systems and a standard "source of truth"
lsmod | grep -q $pattern
$ lsmod | grep -q msr
$ echo $?
0
$ lsmod | grep -q duediligencemuch
$ echo $?
1

Related

Make `patch` return 0 when skipping an already applied patch

I have a build tool that runs a patch command and if the patch command returns non-zero, it will cause the build to fail. I am applying a patch that may or may not already be applied, so I use the -N option to patch, which skips as it should. However, when it does skip, patch is returning non-zero. Is there a way to force it to return 0 even if it skips applying patches? I couldn't find any such capability from the man page.
Accepted answer did not work for me because patch was returning 1 also on other types of errors (maybe different version or sth).
So instead, in case of error I am checking output for "Skipping patch" message to ignore such but return error on other issues.
OUT="$(patch -p0 --forward < FILENAME)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false);
I believe that the following recipe should do the trick, it is what I am using in the same situation;
patches: $(wildcard $(SOMEWHERE)/patches/*.patch)
for patch_file in $^; do \
patch --strip=2 --unified --backup --forward --directory=<somewhere> --input=$$patch_file; \
retCode=$$?; \
[[ $$retCode -gt 1 ]] && exit $$retCode; \
done; \
exit 0
This recipe loops over the dependencies (in my case the patch files) and calls patch for each one. The "trick" on which I am relying is that patch returns 1 if the patch has already been applied and other higher numbers for other errors (such as a non existent patch file). The DIAGNOSTICS section of the patch manual entry describes the return code situation. YMMV
You can also do that as a one line only
patch -p0 --forward < patches/patch-babylonjs.diff || true
So if you want to apply the patch and make sure that's it's working:
(patch -p0 --forward < patches/patch-babylonjs.diff || true) && echo OK
No matter whether the patch has already been applied or not, you'll always get "OK" displayed here.
Below is a script that iterates on the above idea from #fsw and handles removal of .rej files as necessary.
#! /bin/sh
set +x
set -euo pipefail
bn=$(basename "$0")
patch="$1"; shift
r=$(mktemp /tmp/"$bn".XXXX)
if ! out=$(patch -p1 -N -r "$r" < "$patch")
then
echo "$out" | grep -q "Reversed (or previously applied) patch detected! Skipping patch."
test -s "$r" # Make sure we have rejects.
else
test -f "$r" && ! test -s "$r" # Make sure we have no rejects.
fi
rm -f "$r"

.zshrc unrecognized condition on $-

I'm attempting to port over some functionality from my old .bashrc into my .zshrc and I'm having trouble with a condition that worked in bash.
Whenever I remote log in to my computer, I had bash check the $- variable to see if it was interactive. If it was, I would start up an emacs server if one wasn't already running and change to my code directory. Otherwise (if I was getting a file with scp, for example), I wouldn't do anything.
Here's the bit of code:
if [[ $- -regex-match "i" ]]; then
ps -u myusername | grep emacs > /dev/null
if [ $? -eq 0 ]; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi
And here's the error zsh gives me: .zshrc:125: unrecognized condition:$-'`
Does anyone know how to get around this error when using $- ? I've tried quoting it, wrapping it in $(echo $-) but none have worked. Thanks in advance.
Edit: If I switch my code to:
if [[ $- =~ "i" ]]; then
ps -u myusername | grep emacs > /dev/null
if [ $? -eq 0 ]; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi
I now get: .zshrc:125: condition expected: =~ I'm not sure exactly what zsh is interpreting incorrectly here as I'm not very familiar with the semantics of zsh's shell scripts. Could someone point me in the right direction on how to express this condition in zsh?
In zsh, you don't need to bother with $-, which is--I think--intended primarily for POSIX compatibility.
if [[ -o INTERACTIVE ]]; then
if ps -u myusername | grep -q emacs; then
echo "emacs server already running"
else
emacsserver
fi
aliastocdtomydirectory
fi
-regex-match is only available if tho module zsh/regex (man 1 zshmodules) is loaded. (The error message depends on the version: I get zsh: unknown condition: -regex-match if it is not loaded on 4.3.17, but zsh:1: unknown condition: -$- on 4.3.10).
You can try [[ $- =~ "i" ]] which is not dependend on additional modules.

Can tar -xvf be used in a If statement to return true or false

I know I might sound weird but I was wondering if I could do a if [ tar -xvf ] on some file and that will return me true or false .
I need to write something to a file if the tarring was successful and if not then something else is written on the same file.
something like
if[ find . -maxdepth 1 -name "*.tar" -exec tar -xvf {} ] ; then
echo " Untar Successful"> test.txt
else
echo "Untar Not Successful"> test.txt
Please let me know if there is something I can do to implement this
EXIT STATUS
The tar utility exits 0 on success, and >0 if an error occurs.
You can check error like
if [ $? -ne 0 ]; then
Where $? is the most recent foreground pipeline exit status.
You cannot reliably use the status of find to determine whether the commands it executes executed successfully. The POSIX definition of find says:
find
EXIT STATUS
The following exit values shall be returned:
0 All path operands were traversed successfully.
>0 An error occurred.
This is different from saying anything about the exit statuses of any executed commands.
The xargs utility does provide the information you need. POSIX says:
xargs
EXIT STATUS
The following exit values shall be returned:
0 All invocations of utility returned exit status zero.
1-125 A command line meeting the specified requirements could not be assembled, one or more of the invocations of utility returned a non-zero exit status, or some other error occurred.
126 The utility specified by utility was found but could not be invoked.
127 The utility specified by utility could not be found.
So, you could use:
if find . -maxdepth 1 -name "*.tar" -print0 | xargs -0-L 1 tar -xf
then echo "Untar Successful"
else echo "Untar Not Successful"
fi > test.txt
Note that this only uses one redirection. It tests the exit status of the pipeline, which is the exit status of the last command in the pipeline, which is the exit status of xargs, which tells you whether it worked or not.
The -print0 and -0 options are GNU extensions to the POSIX standard. As long as your filenames do not contain spaces or newlines or tabs, you can safely use -print (and no corresponding argument to xargs) instead.
You can do:
find ... -exec sh -c 'tar ... && echo success || echo failure'
or
find ... -exec sh -c 'if tar ...; then echo success; else echo failure; fi'
(This emits a message for every file, and you can include the path of the tar
file by putting {} in the echoed message. If you want to make one report at
the end stating that all of the tars were successful, you could do something like:
if find ... -exec sh -c 'tar ... && echo success || echo failure' |
grep failure > /dev/null; then
echo "untar failed"
else
echo "untar successful"
fi
but that seems less useful to me.
You can definitely do "tar -tf" on tar files. Options may very according to the extensions you have. You can also add options "v" for verbose.
tar -Jtf "ABC.tar.xz"
tar -jtf "ABC.tar.bzip2"
tar -tf "ABC.tar"
You can even find list of files.
tar -tf "ABC.tar" "./ABC/hello.c" >/dev/null 2>&1
If file hello.c is present in zip file, it will return success(0) otherwise it will return error code.

how to translate the hostname solaris?

can any one translate or explain the following unix script for me please, when i actually run the script in the solaris server, it gives me the server name, but not really sure how this script work, can any one explain it in simple baby language ? Thanks
TEXTDOMAIN=SUNW_OST_OSCMD export TEXTDOMAIN
if [ $# -eq 0 ]; then
/bin/uname -n
elif [ $# -eq 1 ]; then
/bin/uname -S $1
else
echo `/bin/gettext "Usage: hostname [name]"`
exit 1
fi
$# reads command line arguments
if there are none call uname -n
if there is one call uname -S $1 (which is the command line argument.)
See man uname to discover the differences in these calls.
If the script is executed with 0 arguments
it will just run uname manpage printing you system name
if script is executed with 1 argument
it will change your system name ( you have to be superuser)
else prints usage

shell script help - checking for file exists

I'm not sure why this code isn't working. Its not going to the copy command.
I successfully run this manually on the command line (without the check)
I don't think i'm performing a correct file check? Is there a better, cleaner way to write this?
I just want to make sure the file exists, if so, copy it over. Thanks.
#!/bin/bash
if [ $# != 1 ]; then
echo "Usage: getcnf.sh <remote-host>" 2>&1
exit 1
fi
#Declare variables
HOURDATE=`date '+%Y%m%d%H%M'`
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
BACKUP_DIR=/home/mysql/dev/logs/
export REMOTE_MYCNF HOURDATE STAMP
#Copy file over
echo "Checking for mysoft.log file $REMOTE_MYCNF $STAMP" 2>&1
if [ -f $REMOTE_MYCNF ]; then
echo "File exists lets bring a copy over...." 2>&1
/usr/bin/scp $1:$REMOTE_MYCNF $BACKUP_DIR$1.mysoft.log
echo "END CP" 2>&1
exit 0
else
echo "Unable to get file" 2>&1
exit 0
fi
your checking existing file on remote computer seems like:
you should do:
ssh $host "test -f $file"
if [ $? = 0 ]; then
use sh -x script.sh to see what is happening.
You are testing for the existence of a remote file
$1:$REMOTE_MYCNF
using the local name $REMOTE_MYCNF. The if test is never satisfied.
You don't check that $1 is set.
Your file check runs on the local machine - not on the remote.
Change your if to:
if[! -f $REMOTE_MYCNF -o ! -d $REMOTE_MYCNF];

Resources