Closing open file descriptors from /proc/pid/fd

Hi guys,

i need to write a shell script that will close file descriptors from /proc/pid/fd

will calling exec 4<&- solve the problem ?

thanks in advance :slight_smile:

are you trying to close a file descriptor of another process?

hi frank_rizzo

i am basically doing a ps-ef | grep <an application>

going to the /proc/pid/fd and trying to close some open files

process=your_process_name;for i in $(ps -ef|grep $process|grep -v grep|awk '{print $2}'); do 
echo -e "Printing Open Files by $process with $i PID\n$(lsof -p $i|awk 'NR>1')"
read -p "Dou you want to close $process with $i PID..[y/n]" c;if [ "$c" = "y" ] ; then kill $i;fi;done

if you close the process then open files was closed automatically by process if process has signal handlers,
if not , kernel executes default handler on process..

regards
ygemici

hi ygemici,

thanks for the suggestions :slight_smile: . But i don't want to end the process. the process is a 24*7 running application. i shouldn't kill it.

I need to only close certain open file descriptors.

regards
romeo

I believe it's impossible in general case. An application can close all or some files on some signals and do not exit but it depends on this concrete application.

yazu,

what will happen if i attempt to do a 5>&- from /proc/pid/fd ??.. will the fd not be closed ?

regards
romeo

If you means exec 5>&- you close the file descriptor #5 opened by your shell (if it was opened or nothing happens).

if your process always works,why do you need close the opened files belong to your process?
if you want to close fd n your script you can use this
test still fd is open?

lsof -a -d3|grep $$

and or you can use like this..

# ./chkfd filetest

-- chkfd code for 3fd(u)--

#!/bin/bash
exec 3<> $1
echo "3.FD is opened now.."
lsof -a -d3|grep $$
exec 3>&-
if [[ $(lsof -a -d3|grep $$|grep -v pipe) = "" ]] ; then
echo -e "\n3.FD is closed successfully" ;
else echo -e "\n3.FD maybe is still open, check your script code"
lsof -a -d3|grep $$
fi

ygemici,

so exec 3&gt;&- works.. thanks :\).. that answers my question. 

i want to close the fds because there are too many open fds in the process and that is causing performance issues. I know it needs to be addressed in application and this is only a work around to close the fds from shell. i am looking for a temporary fix only.

Thanks all for your inputs

you cann't/mustn't close fds belong to any process that opened fds( in -> /proc/PID/fd) by with `FDN>&-` command.For this with safely,you must kill the process..

But if you cannot kill it and you are sure what will be happened or wll be not happened after close fds then you can execute these(below comms/calls) but I dont recommend this way for this job.

# ls -1 /proc/PID/fd ##(find fds)
gdb --pid PID #(attach process by debugger)
.......
.......
(gdb) p close(1) 
(gdb) p close(2) 
......
(gdb) p close(X) 
detach
quit
p close (1) --> print & close(syscall) the "FD 1" belong to PID
....

regards
ygemici

1 Like

thanks ygemici , it matches my requirements

Hey,

I am triggering the gdb from script like:
gdb -command=file -p pid

it is running but saying hit return to continue.

how can i give gdb command so that it is ran as a silent command with out need for any user input ??

You have got a really poorly designed application if you have to go in and close file handles in the manner you describe.

Why not fix the application?

i understand that fpmurphy, i am making changes in the application. this is only for a temporary fix

---------- Post updated at 09:49 PM ---------- Previous update was at 09:47 PM ----------

Anyway,
i got the answer.

gdb -p pid >input.txt <output.txt

i am simply redirecting the input and output and i am providing all commands that need to be run by gdb in the input file

>close_fd;for i in $(ls -1 /proc/YOURPID/fd/);do echo "call close($i)">>close_fd;done
echo -e "detach\nquit">>close_fd;gdb -p YOURPID -x close_fd

regards
ygemici