Я пытаюсь понять скрипты оболочки и передать переменные окружения, а что нет.
Я пытаюсь выполнить скрипт PHP из TextWrangler, который в свою очередь открывает новый скрипт PHP с терминалом. (TextWrangler - это текстовый редактор, который может выполнять сценарии, расположенные в указанной папке, например, для работы с текущим активным документом).
Первый скрипт находится в:
/Users/<username>/Library/Application Support/TextWrangler/Scripts/
... и его содержание:
#!/usr/bin/php
<?php
var_dump( $_SERVER );
chdir( __DIR__ );
$file = realpath( '../Unix Support/test.php' );
exec( sprintf( 'open -a Terminal "%s" &', $file ) );
exit( 0 );
?>
Второй в:
/Users/<username>/Library/Application Support/TextWrangler/Unix Support/
... и его содержание:
#!/usr/bin/php
<?php
var_dump( $_SERVER );
exit( 0 );
?>
TextWrangler передает некоторые переменные окружения первому скрипту (к которому я могу получить доступ через $_SERVER
), и они соответствуют ожиданиям. Например, правильный путь к файлу текущего документа, который активен в TextWrangler.
При первом выполнении сценария переменные среды автоматически автоматически передаются во второй сценарий (который я также открываю с помощью exec()
).
Теперь наступает расстраивающая часть: когда я переключаю активный документ в TextWrangler и снова запускаю сценарий, первый сценарий снова получает правильные переменные среды от TextWrangler, но второй сценарий все еще имеет старые переменные среды, если только я заранее не уничтожил Terminal. Очевидно, что сеанс терминала как-то запоминает первые переменные среды и не хочет обновляться.
Но кроме этого самого базового понимания, я не имею ни малейшего представления о том, как работают переменные среды, какова их область действия и т.д. Итак, кто-то может объяснить, как я могу сделать это так (если возможно, для начала), что второй скрипт снова получает правильные переменные окружения, без необходимости каждый раз завершать работу терминала?
Я пытался явно установить переменные окружения в первом скрипте перед вызовом exec()
, вот так:
foreach( $_SERVER as $key => $value )
{
putenv( "$key=$value" );
}
exec( ... etc. );
Я попытался сбросить переменные окружения в конце, как в первом, так и во втором скриптах, вот так:
foreach( $_SERVER as $key => $value )
{
putenv( "$key" );
}
Но ничего не работает, как я ожидаю. Любые новые идеи тщательно оценены.
редактировать:
Тем временем я нашел альтернативное, но неудовлетворительное решение: когда я вызываю open -n -a Terminal ...
(обратите внимание на добавленный аргумент -n
) с помощью exec()
, он каждый раз запускает новый сеанс Terminal с правильные переменные среды. Но это каждый раз открывает совершенно новый экземпляр Terminal.
Обновить:
Я немного упростил процесс, используя только один сценарий вместо двух, тестируя переменную окружения SHLVL
. Мне также удалось покончить с новым экземпляром Terminal, используя временный файл, как предложил Скотт. Это привело к следующему. Но я все еще чувствую, что это не очень элегантно.
$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" );
}
}
Так что я все еще открыты для других предложений (кроме CLI и файловых предложений, которые Скотт уже предлагал). Если, конечно, это просто невозможно (Скотт, казалось, уже намекал на это).