Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have by accident overritten a very complex bash script, where I tried to implement scoping and threading in a tidy way

now the same script is still running but the file is no more, question is: Is it possible to scan through the ram and find the sting representation of the file itself ?

Another problem ist: i can't find the /dev/mem or /dev/kmem file, already tried to grep it for contents

To the enviremoent: It's a debian/sid machine (vps) hostet on vpsfx.com

root@heisenberg:~# ls -a /dev
.        kmsg   ptyp2  ptyp9  random  tty1   tty5   ttyp2  ttyp9  urandom
..       log    ptyp3  ptypa  shm     tty10  tty6   ttyp3  ttypa  xconsole
.udev    null   ptyp4  ptypb  stderr  tty11  tty7   ttyp4  ttypb  zero
char     ptmx   ptyp5  ptypc  stdin   tty12  tty8   ttyp5  ttypc
console  pts    ptyp6  ptypd  stdout  tty2   tty9   ttyp6  ttypd
fd       ptyp0  ptyp7  ptype  tty     tty3   ttyp0  ttyp7  ttype
full     ptyp1  ptyp8  ptypf  tty0    tty4   ttyp1  ttyp8  ttypf
share|improve this question

2 Answers 2

up vote 11 down vote accepted

Have a look at /proc/$PID/fd. There you should have all the file descriptors openned by the process, including the script itself. Just cat $FD > /tmp/yourscript.sh should be enough to recover it.

share|improve this answer
    
I upvoted this answer despite the fact that it does not in fact answer the question that the OP asked. The OP asked how to recover the script from RAM, not from the filesystem. This answer uses the files system, relying on the fact that the script file is not finally unlinked until the final reference count reaches zero. –  Jonathan Ben-Avraham Dec 26 '13 at 6:53
    
The proc filesystem resides in RAM only and almose everybody has it mounted. –  diegows Dec 27 '13 at 11:32
1  
The /proc fs does not reside in RAM. In fact, it does not reside anywhere. See unix.stackexchange.com/questions/74713/…. Although you can get the fd from /proc, cating the fd reads the file from fs, not RAM. True, you deleted the file, reducing the inode ref count, and no one else can see it now, but it is not actually deleted from the fs until the process running the script closes it. See stackoverflow.com/questions/2028874/…. –  Jonathan Ben-Avraham Dec 27 '13 at 12:18
    
Yes, you are right. The file itself is read from the disk filesystem. /proc exists in RAM, it's not like a ramdisk, but the information is in RAM. With the exception of /proc/$PID/fd and may be other. Anyway, @Thomas Nordquist wants to recover the file, and this is thse easy way. –  diegows Dec 27 '13 at 14:01
    
Worked for me, after a few trys I found the correct file descriptor finally i can close the process and continue –  Thomas Nordquist Jan 9 at 15:44

Assuming that the OP really meant from RAM and not any possible way, and assuming that the process in which the script was executed has zero core file limit (which is usually the default setting, cat /proc/PID/limits), then you need to attach to the process and either set the core limit to a large enough value to include the process image and the use the ABRT signal to generate the core file, or use a tool such as gdb that can attach to a process and generate a core image of the process from RAM.

  1. Install gdb

In some shell with same ownership as the running script or root ownership:

  1. Do ps ax to find the process id (PID)
  2. gdb -p PID

Note that this will stop the process execution from continuing but not remove it from the process table.

  1. In gdb issue command generate-core-file

gdb should repond with something like Saved corefile core.15113, assuming that PID is 15113.

  1. In gdb issue command detach

Your script will continue running.

  1. In gdb issue command quit
  2. In shell, run strings core.15113 > my_script.sh

Open the my_script.sh in some editor. Your script text should be towards the end of the file before the environment section. Use the editor to scrape off the sections before and after the script.

Test this solution on another script before you use it on your prize script, YMMV.

The sequence looks like this:

yba@tavas:~$ gdb -p 15113
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 15113
Reading symbols from /bin/bash...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libtinfo.so.5...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libtinfo.so.5
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libdl.so.2
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007feaf4b4c7be in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) generate-core-file
Saved corefile core.15113
(gdb) detach
Detaching from program: /bin/bash, process 15113
(gdb) quit
yba@tavas:~$ 
share|improve this answer
    
This solution works too, but here is some digging involved, thank for your help –  Thomas Nordquist Jan 9 at 15:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.