If I do a
w, I can see that a user is editing a certain file in vi.
However there are several files with the same name in different directories.
How do I see which of these files is the one that the user is editing?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.Sign up to join this community
You can use
lsof selecting the user and searching for the
vim process as in:
sudo lsof -u user -a -c vim | grep swp
As @Fox point outs, the classical
vi creates a temp file on
/var/tmp so the alternative to see it, should be (not tested).
sudo lsof -u user -a -c vi | grep '/var/tmp/'
However, as @Fox points out, you won't be able to correlate it with the classical
vi to the actual file, and then you would need the tools I talk about next on the answer (for classical
vim it would suffice the
lsof); usually nowadays in Linux you are using
vim when invoking
Returning to the
vim example, we will see then the swap file being used named after
file is opened as in
user1 is doing
$ sudo lsof -c vi -a -u user1 | grep swp vi 3615 user1 3u REG 8,1 12288 265061 /home/user1/.file.swp
-a causes list selection options to be ANDed
-cc This option selects the listing of files for processes executing the command that begins with the characters of c. Multiple commands may be specified, using multiple -c options. They are joined in a single ORed set before participating in AND option selection.
-u s This option selects the listing of files for the user whose login names or user ID numbers are in the comma-separated set s
lsof, you can also use as root,
sysdig, which is a powerful debugging framework:
This will show all files open in the system in real time, listing user,pid and process as soon as they are opened:
sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open"
sysdig: system-level exploration and troubleshooting tool
Sysdig instruments your physical and virtual machines at the OS level by installing into the Linux kernel and capturing system calls and other OS events. Then, using sysdig's command line interface, you can filter and decode these events in order to extract useful information and statistics.
Sysdig can be used to inspect live systems in real-time, or to generate trace files that can be analyzed at a later stage.
As other useful tool for sysadmins, you can also install
snoopy, which logs all invocations of processes called to syslog. If the user invokes in the command line
vi file, you will see it in the system logs.
Beware that after
snoopy is installed, it will be logging all the process invocations via execve() until you uninstall it (which you might want or not want to be happening all the time).
snoopy: execve() wrapper and logger
snoopy is merely a shared library that is used as a wrapper to the execve() function provided by libc as to log every call to syslog (authpriv). system administrators may find snoopy useful in tasks such as light/heavy system monitoring, tracking other administrator's actions as well as getting a good 'feel' of what's going on in the system (for example Apache running cgi scripts).
$sudo apt-get install snoopy sysdig
See also the related question: Understanding what a Linux binary is doing
This might work for some cases. You can us
ps to find the process id of the
vi instance editing the file:
$ w ... username pts/2 :0.0 11:42 2:34m 0.28s 0.27s vim foo $ ps aux | grep 'vim foo' ... username 55899 .... vim foo
Then, as root, look at the open file descriptors associated with that pid:
# ls -l /proc/55899/fd ... lrwx------ 1 username group 64 Feb 8 14:23 6 -> /path/to/.foo.swp
Given that, then you might be able to conclude that the file is
I'm assuming that you know what command the user ran, but that you want to know which directory they ran it from (so that if they ran
vi myfile.txt, you know whether that's
/tmp/myfile.txt, or something else).
In that case, assuming you're running as root, you can do:
<pid> is the process ID of the
vim process you're interested in - that will tell you the current directory of that process, which has a good chance of being the one you want.
Note, however, that:
:cdcommand). You may also wish to check the current directory of the shell process that spawned the editor, though that's not 100% reliable either.
If you don't have root but do have permissions to read the directories, your best bet is probably to look for the
.swp files for the file in question (assuming the user hasn't changed vim's default swap location!):
$ find . -type f ./1/foo ./0/foo ./2/foo $ cd 1 $ vi foo ^Z  19650 $ cd .. $ find -type f ./1/foo ./1/.foo.swp ./0/foo ./2/foo
Note, however, if you edit
.foo in the same directory,
vim will need to make different temporary filename extensions:
-rw-r--r-- 1 user grp 12288 Feb 8 14:59 .foo.swo -rw------- 1 user grp 4096 Feb 8 14:58 .foo.swp
So you may wish to look using
find . -user username -name '.*.sw*'
This feels a bit like an XY problem -- what larger problem are you trying to solve? If you're trying to manage multiple users editing common files, you may wish to move to a source management system.