Search code examples
bashpid

Use the PID of a prog as an argument of this same prog


I have a C program which waits a string as argument, I can use it like that:

./myprog "hello"

What I want to do is:

  • Start the program without argument
  • Get the PID of this prog
  • Use this PID as a base to make a string
  • Pass this string as the argument of the running prog.

I know how to get the pid. I can do it so:

./myprog &
PID=$!

I have another prog to calculate the string I want with this pid:

./StringFromPid $PID

What I don't know is: how to use the result of this last line as the input of myProg (which is already launch, but without his string arg, knowing that when it's launched without arg it will simply close...)

I've tried:

./StringFromPid $PID | ./myprog

But there's two problems with it:

  1. It launches another instance of myprog, which has another pid, so that's not what I want.

  2. For some reason, it doesn't even work. I mean, the output of ./StringFromPid $PID is not used as input for ./myprog. It just close, like if there were no arg.

I can't modify myprog, but I can modify StringFromPid; I can even put the code of StringFromPid in my bash script since it's not big at all. And I've read a lot of tuto about bash script but I'm still new to it (not a lot of practice)

I've found a solution, but it's not optimal (far from it):

#!/bin/bash
./myprog $(echo $(./StringFromPid $(let "a = $$";let "b = 5"; let "c = a + b"; echo $c)))

The +5 is because I just found that when I launch this script, there is a +5 difference between his PID and myprog PID. No idea why, but it works.

However I'm still open for better solutions. In fact this work on my pc (I'm on Ubuntu 16.04 by the way,) but at the end it must work on the CTF server where I have no admin rights


Solution

  • Simplest way is to exec the C program.

    #!/bin/bash
    
    # pid of current shell
    PID1=$$
    echo $PID1
    
    # do stuff
    
    (
        # this is a subshell
    
        # $$ doesn't change but BASHPID does
        PID2=$BASHPID
        echo $PID2
    
        # the pid of this C program will be $PID2
        exec myCprogram $(./StringFromPid $PID2)
    
        # exec doesn't return
        echo "can't get here"
    )
    
    # do more stuff
    
    

    If you're on a platform that supports it, it may be possible to use the LD_PRELOAD trick to override getpid().

    But exec is simpler.