I am running a PHP script from the CLI. In that PHP script I would like to execute a few commands from the command line using system()
. Perhaps this isn't the right tool for the job, and I could probably just wrap the PHP script in a shell script, but I want to know if it's possible to do completely within the PHP script.
When I do this in a terminal it works fine:
user@host:~$ workon pootle
(pootle)user@host:~$
However this doesn't work from PHP (being executed as the same user).
#!/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
I notice that the output for the last two is exactly the same as when executing by a terminal, but the first one is different. I thought it might be an alias, however it doesn't appear to be. alias | grep -i workon
alias | grep -i workon
shows no output.
I also compared all of the environment variables returned from command line env
and PHP system('env')
, and all but _
are exactly the same, including SHELL=/bin/bash
.
The output of which workon
executed by the terminal is empty.
Edit
Maybe I'm getting somewhere with this.
user@host:~$ type workon
workon is a function
workon ()
{
typeset env_name="$1";
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 $1
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
if [ ! "$1" = "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
I found this by installing virtualenvwrapper
and then i ran
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
and saw VIRTUALENVWRAPPER_SCRIPT
... pretty easy to figure out from there
To be able to execute the virtualenvwrapper functions, we need to first source
the virtualenvwrapper.sh
file. To find the location of that file, in a terminal execute:
which virtualenvwrapper.sh
If that doesn't produce any output, use find
to find it.
find /usr/ -name "virtualenvwrapper.sh"
For me, the location was /usr/local/bin/virtualenvwrapper.sh
When PHP does system calls, it uses sh
:
<?php
system('echo $0'); // echoes 'sh'
However the virtualenvwrapper.sh
script fails when being executed with sh
, so we need to use bash
instead.
Another thing to note is that PHP system calls are separate subshells from each other, so if you do:
<?php
system('FOO=BAR');
system('echo $FOO');
This prints out an empty line. Where as the following prints BAR
:
<?php
system('FOO=BAR && echo $FOO');
Therefore, we need to:
workon
to change working virtual environments This is what I came up with and appears to be working correctly:
<?php
$commands = [
'source /usr/local/bin/virtualenvwrapper.sh',
'workon pootle',
'pootle update_stores --project=AIWeb',
];
system('/bin/bash -c "'.implode(' && ', $commands) .'"');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.