你如何从 PHP exec 调用 python 命令 "workon"?
How do you call python command "workon" from PHP exec?
我是 运行 来自 CLI 的 PHP 脚本。在那个 PHP 脚本中,我想使用 system()
从命令行执行一些命令。也许这不是完成这项工作的正确工具,我可能只是将 PHP 脚本包装在 shell 脚本中,但我想知道是否可以完全在 [=41] 中完成=] 脚本.
当我在终端中执行此操作时,它工作正常:
user@host:~$ workon pootle
(pootle)user@host:~$
然而,这不适用于 PHP(作为同一用户执行)。
#!/usr/bin/env php
<?php
system('workon pootle'); // sh: 1: workon: not found
system('/bin/bash workon pootle'); // /bin/bash: workon: No such file or directory
system('/bin/sh workon pootle'); // /bin/sh: 0: Can't open workon
我注意到最后两个的输出与终端执行时的输出完全相同,但第一个不同。我认为它可能是一个别名,但它似乎不是。 alias | grep -i workon
显示无输出。
我还比较了从命令行返回的所有环境变量 env
和 PHP system('env')
,除了 _
之外的所有环境变量都完全相同,包括 SHELL=/bin/bash
.
终端执行which workon
输出为空
编辑
也许我对此有所了解。
user@host:~$ type workon
workon is a function
workon ()
{
typeset env_name="";
if [ "$env_name" = "" ]; then
lsvirtualenv -b;
return 1;
fi;
virtualenvwrapper_verify_workon_home || return 1;
virtualenvwrapper_verify_workon_environment $env_name || return 1;
activate="$WORKON_HOME/$env_name/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate";
if [ ! -f "$activate" ]; then
echo "ERROR: Environment '$WORKON_HOME/$env_name' does not contain an activate script." 1>&2;
return 1;
fi;
type deactivate > /dev/null 2>&1;
if [ $? -eq 0 ]; then
deactivate;
unset -f deactivate > /dev/null 2>&1;
fi;
virtualenvwrapper_run_hook "pre_activate" "$env_name";
source "$activate";
virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`;
eval "$virtualenvwrapper_original_deactivate";
unset -f deactivate > /dev/null 2>&1;
eval 'deactivate () {
# Call the local hook before the global so we can undo
# any settings made by the local postactivate first.
virtualenvwrapper_run_hook "pre_deactivate"
env_postdeactivate_hook="$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate"
old_env=$(basename "$VIRTUAL_ENV")
# Call the original function.
virtualenv_deactivate
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
if [ ! "" = "nondestructive" ]
then
# Remove this function
unset -f virtualenv_deactivate >/dev/null 2>&1
unset -f deactivate >/dev/null 2>&1
fi
}';
virtualenvwrapper_run_hook "post_activate";
return 0
}
bash /usr/share/virtualenvwrapper/virtualenvwrapper.sh workon
我通过安装 virtualenvwrapper
找到了这个,然后 运行
env | grep VIRTU
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
VIRTUALENVWRAPPER_SCRIPT=/usr/share/virtualenvwrapper/virtualenvwrapper.sh
VIRTUALENVWRAPPER_HOOK_DIR=/root/.virtualenvs
_VIRTUALENVWRAPPER_API= mkvirtualenv rmvirtualenv lsvirtualenv showvirtualenv workon add2virtualenv cdsitepackages cdvirtualenv lssitepackages toggleglobalsitepackages cpvirtualenv setvirtualenvproject mkproject cdproject mktmpenv
并看到 VIRTUALENVWRAPPER_SCRIPT
...从那里很容易弄清楚
为了能够执行 virtualenvwrapper 函数,我们需要先 source
virtualenvwrapper.sh
文件。要找到该文件的位置,请在终端中执行:
which virtualenvwrapper.sh
如果没有产生任何输出,请使用 find
找到它。
find /usr/ -name "virtualenvwrapper.sh"
对我来说,位置是 /usr/local/bin/virtualenvwrapper.sh
PHP做系统调用时,使用sh
:
<?php
system('echo [=12=]'); // echoes 'sh'
然而 virtualenvwrapper.sh
脚本在使用 sh
执行时失败,所以我们需要使用 bash
代替。
另一件需要注意的事情是 PHP 系统调用是彼此独立的子 shell,因此如果您这样做:
<?php
system('FOO=BAR');
system('echo $FOO');
这会打印出一个空行。其中打印出 BAR
:
<?php
system('FOO=BAR && echo $FOO');
因此,我们需要:
- 使用bash代替sh
- 来源 virtualenvwrapper.sh
- 执行
workon
以更改工作虚拟环境
- 执行任何其他需要的命令
- 一行完成所有这些
这是我想出的并且似乎工作正常:
<?php
$commands = [
'source /usr/local/bin/virtualenvwrapper.sh',
'workon pootle',
'pootle update_stores --project=AIWeb',
];
system('/bin/bash -c "'.implode(' && ', $commands) .'"');
我是 运行 来自 CLI 的 PHP 脚本。在那个 PHP 脚本中,我想使用 system()
从命令行执行一些命令。也许这不是完成这项工作的正确工具,我可能只是将 PHP 脚本包装在 shell 脚本中,但我想知道是否可以完全在 [=41] 中完成=] 脚本.
当我在终端中执行此操作时,它工作正常:
user@host:~$ workon pootle
(pootle)user@host:~$
然而,这不适用于 PHP(作为同一用户执行)。
#!/usr/bin/env php
<?php
system('workon pootle'); // sh: 1: workon: not found
system('/bin/bash workon pootle'); // /bin/bash: workon: No such file or directory
system('/bin/sh workon pootle'); // /bin/sh: 0: Can't open workon
我注意到最后两个的输出与终端执行时的输出完全相同,但第一个不同。我认为它可能是一个别名,但它似乎不是。 alias | grep -i workon
显示无输出。
我还比较了从命令行返回的所有环境变量 env
和 PHP system('env')
,除了 _
之外的所有环境变量都完全相同,包括 SHELL=/bin/bash
.
终端执行which workon
输出为空
编辑
也许我对此有所了解。
user@host:~$ type workon
workon is a function
workon ()
{
typeset env_name="";
if [ "$env_name" = "" ]; then
lsvirtualenv -b;
return 1;
fi;
virtualenvwrapper_verify_workon_home || return 1;
virtualenvwrapper_verify_workon_environment $env_name || return 1;
activate="$WORKON_HOME/$env_name/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate";
if [ ! -f "$activate" ]; then
echo "ERROR: Environment '$WORKON_HOME/$env_name' does not contain an activate script." 1>&2;
return 1;
fi;
type deactivate > /dev/null 2>&1;
if [ $? -eq 0 ]; then
deactivate;
unset -f deactivate > /dev/null 2>&1;
fi;
virtualenvwrapper_run_hook "pre_activate" "$env_name";
source "$activate";
virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`;
eval "$virtualenvwrapper_original_deactivate";
unset -f deactivate > /dev/null 2>&1;
eval 'deactivate () {
# Call the local hook before the global so we can undo
# any settings made by the local postactivate first.
virtualenvwrapper_run_hook "pre_deactivate"
env_postdeactivate_hook="$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate"
old_env=$(basename "$VIRTUAL_ENV")
# Call the original function.
virtualenv_deactivate
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
if [ ! "" = "nondestructive" ]
then
# Remove this function
unset -f virtualenv_deactivate >/dev/null 2>&1
unset -f deactivate >/dev/null 2>&1
fi
}';
virtualenvwrapper_run_hook "post_activate";
return 0
}
bash /usr/share/virtualenvwrapper/virtualenvwrapper.sh workon
我通过安装 virtualenvwrapper
找到了这个,然后 运行
env | grep VIRTU
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
VIRTUALENVWRAPPER_SCRIPT=/usr/share/virtualenvwrapper/virtualenvwrapper.sh
VIRTUALENVWRAPPER_HOOK_DIR=/root/.virtualenvs
_VIRTUALENVWRAPPER_API= mkvirtualenv rmvirtualenv lsvirtualenv showvirtualenv workon add2virtualenv cdsitepackages cdvirtualenv lssitepackages toggleglobalsitepackages cpvirtualenv setvirtualenvproject mkproject cdproject mktmpenv
并看到 VIRTUALENVWRAPPER_SCRIPT
...从那里很容易弄清楚
为了能够执行 virtualenvwrapper 函数,我们需要先 source
virtualenvwrapper.sh
文件。要找到该文件的位置,请在终端中执行:
which virtualenvwrapper.sh
如果没有产生任何输出,请使用 find
找到它。
find /usr/ -name "virtualenvwrapper.sh"
对我来说,位置是 /usr/local/bin/virtualenvwrapper.sh
PHP做系统调用时,使用sh
:
<?php
system('echo [=12=]'); // echoes 'sh'
然而 virtualenvwrapper.sh
脚本在使用 sh
执行时失败,所以我们需要使用 bash
代替。
另一件需要注意的事情是 PHP 系统调用是彼此独立的子 shell,因此如果您这样做:
<?php
system('FOO=BAR');
system('echo $FOO');
这会打印出一个空行。其中打印出 BAR
:
<?php
system('FOO=BAR && echo $FOO');
因此,我们需要:
- 使用bash代替sh
- 来源 virtualenvwrapper.sh
- 执行
workon
以更改工作虚拟环境 - 执行任何其他需要的命令
- 一行完成所有这些
这是我想出的并且似乎工作正常:
<?php
$commands = [
'source /usr/local/bin/virtualenvwrapper.sh',
'workon pootle',
'pootle update_stores --project=AIWeb',
];
system('/bin/bash -c "'.implode(' && ', $commands) .'"');