2017-03-02 1 views
1

J'utilise un script PHP de la CLI. Dans ce script PHP, je voudrais exécuter quelques commandes à partir de la ligne de commande en utilisant system(). Peut-être que ce n'est pas le bon outil pour le travail, et je pourrais probablement juste emballer le script PHP dans un script shell, mais je veux savoir s'il est possible de faire complètement dans le script PHP.Comment appelez-vous la commande python "workon" de PHP exec?

Quand je fais cela dans un terminal, il fonctionne très bien:

[email protected]:~$ workon pootle 
(pootle)[email protected]:~$ 

Cependant, cela ne fonctionne pas de PHP (en cours d'exécution en tant que le même utilisateur).

#!/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 

Je remarque que la sortie pour les deux derniers est exactement le même que lors de l'exécution par un terminal, mais le premier est différent. Je pensais que ce pourrait être un alias, mais il ne semble pas l'être. alias | grep -i workon ne montre aucune sortie.

J'ai aussi comparé toutes les variables d'environnement renvoyées de la ligne de commande env et PHP system('env'), et tout sauf _ sont exactement les mêmes, y compris SHELL=/bin/bash.

La sortie de which workon exécutée par le terminal est vide.

Modifier

Peut-être que je suis quelque part avec ce faire.

[email protected]:~$ 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 
} 
+0

'echo $ (qui WorkOn)' (exécuter que du terminal shell et reportez-vous au chemin) –

+0

@JoranBeasley La sortie est vide. – Mike

+1

dans ce cas, je ne crois pas que workon est accessible depuis le terminal soit ... 'workon --help && echo $ (quel workon)' –

Répondre

0

Pour pouvoir exécuter les fonctions virtualenvwrapper, nous devons d'abord source le fichier virtualenvwrapper.sh. Pour trouver l'emplacement de ce fichier, dans un terminal exécuter:

which virtualenvwrapper.sh 

Si cela ne produit aucune sortie, utilisez find pour le trouver.

find /usr/ -name "virtualenvwrapper.sh" 

Pour moi, l'emplacement était /usr/local/bin/virtualenvwrapper.sh

Lorsque PHP fait des appels système, il utilise sh:

<?php 
system('echo $0'); // echoes 'sh' 

Cependant le script virtualenvwrapper.sh échoue lorsqu'il est exécuté avec sh, donc nous devons utilisez plutôt bash.

Une autre chose à noter est que les appels système PHP sont séparés sous-couches de l'autre, donc si vous faites:

<?php 
system('FOO=BAR'); 
system('echo $FOO'); 

Ceci affiche une ligne vide.Où les impressions suivantes: BAR

<?php 
system('FOO=BAR && echo $FOO'); 

Par conséquent, nous devons:

  • Utilisez bash au lieu de sh
  • Source du virtualenvwrapper.sh
  • Exécuter workon changer les environnements virtuels de travail
  • Exécuter toutes les autres commandes nécessaires
  • en une seule ligne

C'est ce que je suis venu avec et semble fonctionner correctement:

<?php 
$commands = [ 
    'source /usr/local/bin/virtualenvwrapper.sh', 
    'workon pootle', 
    'pootle update_stores --project=AIWeb', 
]; 

system('/bin/bash -c "'.implode(' && ', $commands) .'"'); 
0

bash /usr/share/virtualenvwrapper/virtualenvwrapper.sh workon

Je trouve en installant virtualenvwrapper puis je courais

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 

et a vu VIRTUALENVWRAPPER_SCRIPT ... assez facile à comprendre à partir de là

+0

Je n'ai pas la variable d'environnement 'VIRTUALENVWRAPPER_SCRIPT', mais j'ai trouvé'/usr/local/bin/virtualenvwrapper.sh'. L'exécution de '/ bin/bash /usr/local/bin/virtualenvwrapper.sh workon pootle' n'a aucune sortie. – Mike