Nicolas
Nicolas

Reputation: 33

How can I get the PID of a PHP script run as the first command in a pipeline?

I have a command like this one:

php myscript.php |
curl -X POST --data-binary @- "http://localhost/webservice.php/$$/output/"

I use | to send the output of myscript.php to the curl command. I use $$ to get the PID, but this returns the PID of the curl command, not the php command.

In fact, I will use this command line for all my crontab's jobs. Instead of receiving thousands mails, I would like to send every information to my webservice.

So in myscript.php, I call (1 is cronjob ID) :

file_get_contents('http://localhost/webservice.php/1/' . getmypid() . '/start/');
...
file_get_contents('http://localhost/webservice.php/1/' . getmypid() . '/end/');

I try to send the output of myscript.php to a webservice I'm creating.

So I send start / end commands to my webservice. There's only one thing I miss : the output of the PHP if there are warnings or some "echo".

The goal is to redirect the output of the script (which could be a bash script also) to the webservice, using the PID of the PHP command (which I use to identify the process in my webservice).

How can I get the PID of PHP command ? I tried $$ as I found in Stackoverflow, but as you answer, it seems to be the current shell PID...

Thanks by advance !

Upvotes: 1

Views: 2159

Answers (2)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84363

TL;DR

The $$ variable is a special variable. It returns the PID of the invoking shell, which may not be the same as the current shell's PID as stored in $BASHPID. Neither variable has anything to do with PIDs from processes in your pipeline. The Bash manual says:

($$) Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell.

You need to refactor your PHP script and your pipeline to do something different.

Create Unique Directories Properly

You haven't explained what your PHP script is actually doing, so this seems like an X/Y problem. In general, you should be using mktemp or its PHP equivalents:

to create temporary or unique filenames. Since you seem to want to use unique directories, I give that as an example below. However, it might be cleaner to have a single directory containing filenames that are guaranteed to be unique. Your mileage may vary.

Rather than trying to use a PID, you should be using the mktemp utility to create unique directories or filenames without race conditions. If you do this in Bash, you can export the variable to the environment and then use the same directory inside your PHP script. For example:

#!/usr/bin/env bash

# Create a unique temp directory safely.
export DIR=$(mktemp -d)

# Create your output directory for whatever reason.
mkdir "$DIR/output"

# Ensure PHP uses $_ENV["DIR"] to do whatever it's doing. 
php myscript.php | curl -X POST --data-binary @- "file://$DIR/output/"

# Clean up the temp directory at some point.
echo "I did something with '$DIR' so clean it up later." > /dev/stderr

Just Use Unique Files with Prefixes

Rather than using directories, you might also consider using unique filenames with a defined prefix. For example:

# Create files like "/tmp/myscript.D6147vts"
export TEMPFILE=$(mktemp -t myscript)

Then, like before, use $_ENV["TEMPFILE"] in your PHP script. The benefit of this approach is that your filenames are guaranteed to be unique but they're all in one place and have a common prefix. That can make cleanup or finding the right file much easier later on.

If you really need unique directories, use them. However, if you don't really need the directory structure, don't create extra work for yourself: just use unique filenames.

Upvotes: 1

unixmiah
unixmiah

Reputation: 3145

Try ps aux | grep "process id" and the pid if the second column. Parse it with pnp_exec; meaning, store it in an array and extract PID number.

Upvotes: 0

Related Questions