1
1
I'm pulling my hair out trying to understand shell scripting and passing environment variables, and what not.
I'm trying to execute a PHP script from TextWrangler, that in it's turn opens a new PHP script with Terminal. (TextWrangler is a text editor that has the option to execute scripts, located in a designated folder, to operate on the current active document, for instance).
The first script is located in:
/Users/<username>/Library/Application Support/TextWrangler/Scripts/
... and its contents are:
#!/usr/bin/php
<?php
var_dump( $_SERVER );
chdir( __DIR__ );
$file = realpath( '../Unix Support/test.php' );
exec( sprintf( 'open -a Terminal "%s" &', $file ) );
exit( 0 );
?>
The second is in:
/Users/<username>/Library/Application Support/TextWrangler/Unix Support/
... and its contents are:
#!/usr/bin/php
<?php
var_dump( $_SERVER );
exit( 0 );
?>
TextWrangler passes some environment variables to the first script (which I can access through $_SERVER
), and they are as expected. For instance the correct filepath to the current document that is active in TextWrangler.
The first time I execute the script, the environment variables are automatically passed correctly to the second script (that I open with the exec()
) as well.
Now comes the frustrating part: when I switch the active document in TextWrangler and run the script again, the first script receives the correct environment variables from TextWrangler again, but the second script still has the old environment variables, unless I had killed Terminal beforehand. So obviously the Terminal session somehow remembers the first environment variables, and doesn't want to update.
But apart from a this very basic understanding, I don't have the faintest idea how environment variables passing work, what scope they have, etc. So, could somebody explain how I can make it so (if possible, to begin with) that the second script receives the correct environment variables again, as well, without having to kill Terminal each time?
I've tried explicitly setting environment variables in the first script before calling exec()
, like so:
foreach( $_SERVER as $key => $value )
{
putenv( "$key=$value" );
}
exec( ... etc. );
I've tried unsetting the environment variables at the end, in both the first and second scripts, like so:
foreach( $_SERVER as $key => $value )
{
putenv( "$key" );
}
But nothing works as I expect. Any new insights thoroughly appreciated.
edit:
In the meantime I've found an alternative, but unsatisfactory solution: when I call open -n -a Terminal ...
(note the added -n
argument) with exec()
, it starts a new Terminal session each time, with the correct environment variables. But this opens a completely new Terminal instance each time.
update:
I've simplified the process a bit by only using one script in stead of two now, through testing the environment variable SHLVL
. I've also managed to do away with a new Terminal instance now, by using a temporary file, like Scott suggested as well. This resulted in the following. But I still feel it's not very elegant.
$shellLevel = getenv( 'SHLVL' );
if( 1 == $shellLevel )
{
file_put_contents( 'env.dat', serialize( $_SERVER ) );
exec( sprintf( 'open -a Terminal "%s" &', __FILE__ ) );
exit( 0 );
}
else
{
$_SERVER = unserialize( file_get_contents( 'env.dat' ) );
unlink( 'env.dat' );
foreach( $_SERVER as $key => $value )
{
putenv( "$key=$value" );
}
}
So, I'm still open too other suggestions (besides the CLI and file suggestions that Scott already proposed). Unless, of course, it is simply not possible (Scott seemed to hint at this already).
Scott, thanks. Your last suggestion is what I ended up doing in the meanwhile as well, actually. I simplified things by using only one script now, by testing an environment variable called
SHLVL
that is passed, to see if the script is the parent or child, and indeed saving the environment in a temporary file if it's the parent and reading andputenv()
-ing them, if it's the child script. But it's not very elegant. Are you sure there's not a more elegant way of updating the environment variables for the same Terminal session, besides cli or file? – Decent Dabbler – 2013-11-12T02:38:10.173