Get files used by a binary - linux

I am trying to locate a file used by a binary file during its execution. Using strace helps but its way too convoluted, macroed with grep is good enough, but does there exist an utility which can help me dump only files used by a binary?

you can try using:
lsof -p PID of the running process
lsof -c ssh would show all files opened by processes starting with the letter
Or try ltrace or maybe fuser
I've seen strace be used with some complex grep piping.. but it all depends on what exactly the end goal is.
You can also utilize the -e options in strace to filter, example is:
sudo strace -t -e trace=open,close,read,getdents,write,connect,accept whoami >/dev/null
and grep from there..

Related

Bash, display processes in specific folder

I need to display processes, that are running in specific folder.
For example, there are folders "TEST" and "RUN". 3 sql files are running from TEST, and 2 from RUN. So when I use command ps xa, I can see all processes, runned from TEST and RUN together. What I want is to see processes, runned only from TEST folder, so only 3. Any commands, solutions to do this?
You can use lsof for this.
lsof | grep '/path/of/RUN'.
If you want to include both RUN and TEST in same command
lsof | grep -E "/path/of/RUN|/path/of/TEST"
Hope it helps.
You can try fuser to see which processes have particular files open; or, on Linux, examine the /proc/12345/cwd symlink for each of the candidate processes (replace 12345 with the process id of each).
fuser TEST/*.sql
for proc in /proc/[1-9]*; do
readlink "$proc/cwd" | grep -q TEST && echo "$proc"
done
The latter is not portable to other U*xes, though some may offer similar facilities.

lsof "lies" when using options?

I have a problem where my Java application opens too many files. Debugging this issue, I am dependent on using lsof.
However running lsof this way takes too much time (more than one minutt):
lsof |grep "java"
I should be able to run it using the -p option, however it "lies". It shows too few lines.
lsof -p <PID of the java process>
This is my proof :
lsof |grep java | wc -l
1510146
lsof -p 802 | wc -l
4735
The same happens if I use the -u option limiting to username (process owner).
My system is :
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.39-1+deb8u2 (2017-03-07) x86_64 GNU/Linux
Am I missing something ? Is there an alternative to using lsof ?
lsof is not lying.
The output of the command:
lsof |grep java | wc -l
may contain results of files or processes opened by other programs.
The result you are searching for is the result of the command:
lsof -p <PID> | wc -l
You can increase the limit of opened files for the user running your java application adding this line in /etc/security/limits.conf:
<USER> hard nofile 65536
you can check the current user's limits by typing:
su - <USER>
ulimit -a
lsof without parameter lists all open files, including files which are not using file descriptors – such as current working directories, memory mapped library files, and executable text files.
lsof -p <PID> lists open file descriptors. A file descriptor is a data structure used by a program to get a handle on a file, the most well know being 0,1,2 for standard in, standard out, and standard error.
See: https://www.netadmintools.com/art295.html
Based on my observation, it seems that
lsof | grep <pid> | wc -l
will give duplicate count, because every thread in the specified process will add a line, e.g. if your process have 8 threads, the result will be more than 8x the actual file count.
On the other hand,
lsof -p <PID> | wc -l
produce more exact result, because each file is counted (printed) only once.
Although I have not found official reference for this issue yet.

How find out which process is using a file in Linux?

I tried to remove a file in Linux using rm -rf file_name, but got the error:
rm: file_name not removed. Text file busy
How can I find out which process is using this file?
You can use the fuser command, which is part of the psmisc package, like:
fuser file_name
You will receive a list of processes using the file.
You can use different flags with it, in order to receive a more detailed output.
You can find more info in the fuser's Wikipedia article, or in the man pages.
#jim's answer is correct -- fuser is what you want.
Additionally (or alternately), you can use lsof to get more information including the username, in case you need permission (without having to run an additional command) to kill the process. (THough of course, if killing the process is what you want, fuser can do that with its -k option. You can have fuser use other signals with the -s option -- check the man page for details.)
For example, with a tail -F /etc/passwd running in one window:
ghoti#pc:~$ lsof | grep passwd
tail 12470 ghoti 3r REG 251,0 2037 51515911 /etc/passwd
Note that you can also use lsof to find out what processes are using particular sockets. An excellent tool to have in your arsenal.
For users without fuser :
Although we can use lsof, there is another way i.e., we can query the /proc filesystem itself which lists all open files by all process.
# ls -l /proc/*/fd/* | grep filename
Sample output below:
l-wx------. 1 root root 64 Aug 15 02:56 /proc/5026/fd/4 -> /var/log/filename.log
From the output, one can use the process id in utility like ps to find program name
$ lsof | tree MyFold
As shown in the image attached:

strace entire operating system to get strace logs of all processes simultaneously

Currently, I am taking up the long method of doing this by getting a list of processes using the following command
sudo ps -eo pid,command | grep -v grep | awk '{print $1}' > pids.txt
And then iterating through the process ids and executing in background the strace of each process and generating logs for each process with the process id in the log's extension
filename="$1"
while read -r line
do
chmod +x straceProgram.sh
./straceProgram.sh $line &
done < "$filename"
straceProgram.sh
pid="$1"
sudo strace -p $pid -o log.$pid
However, the problem with this approach is that if there is any new process which gets started, it will not be straced since the strace is on the process ids stored in the pids.txt during the first run.
The list of pids.txt can be updated with new process ids, however, I was inquisitive on running a strace at an operating system level which would strace all the activities being performed.
Could there be a better way to do this?
If your resulting filesystem is going to be a kernel filesystem driver, I would recommend using tracefs to gather the information you require. I would recommend against making this a kernel filesystem unless you have a lot of time and a lot of testing resources. It is not trivial.
If you want an easier, safer alternative, write your filesystem using fuse. The downside is that performance is not quite as good and there are a few places where it cannot be used, but it is often acceptable. Note that there is already an implementation of a logging filesystem under fuse.
use the strace -f (fork) option, also I suggest the -s 9999 for more details

What is the best way to identify which syslog daemon is running on Linux?

I'm writing Linux shell script (sh, bash or csh) to identify which syslog daemon is running.
What is the best way to do it?
Since I only consider RHEL and rpm based destribution, Debian and its derivatives can be ignored.
To the best of my knowledge, syslog-ng and rsyslog (the default) are the only ones available on RHEL. You could either probe the process space, see which process currently holds /var/log/syslog open or simply check which syslog daemon is installed (though, it's possible to have them both installed at the same time).
$ lsof /var/log/messages /var/log/syslog 2>&1 | grep syslog
$ rpm -q rsyslog syslog-ng
$ pgrep -u root syslog | xargs ps -p
One could parse the output of lsof to see which processes have the file /var/log/syslog open, a very crude example would be:
sudo lsof | grep /var/log/syslog | cut -f1 -d' '
If you are using a single distribution there may be more elegant ways of checking.
On a debian-based system, run the following script to see what's installed:
dpkg-query -l '*syslog*' | grep ii
This will give you output similar to the following
ii rsyslog 7.4.4-1ubuntu2.3 i386 reliable system and kernel logging daemon
That way you don't have to grep files etc. Hope it helps you out.

Resources