简体   繁体   English

你如何从PHP exec调用python命令“workon”?

[英]How do you call python command “workon” from PHP exec?

I am running a PHP script from the CLI. 我正在从CLI运行PHP脚本。 In that PHP script I would like to execute a few commands from the command line using system() . 在那个PHP脚本中,我想使用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. 也许这不是适合这项工作的工具,我可能只是将PHP脚本包装在shell脚本中,但我想知道是否可以在PHP脚本中完全完成。

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). 但是这不适用于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

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. alias | grep -i workon显示没有输出。

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 . 我还比较了从命令行env和PHP system('env')返回的所有环境变量,除_之外的所有变量都完全相同,包括SHELL=/bin/bash

The output of which workon executed by the terminal is empty. 终端执行的which workon输出为空。

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 我通过安装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

and saw VIRTUALENVWRAPPER_SCRIPT ... pretty easy to figure out from there 并且看到了VIRTUALENVWRAPPER_SCRIPT ......很容易从那里弄清楚

To be able to execute the virtualenvwrapper functions, we need to first source the virtualenvwrapper.sh file. 为了能够执行virtualenvwrapper功能,我们首先需要sourcevirtualenvwrapper.sh文件。 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来查找它。

find /usr/ -name "virtualenvwrapper.sh"

For me, the location was /usr/local/bin/virtualenvwrapper.sh 对我来说,位置是/usr/local/bin/virtualenvwrapper.sh

When PHP does system calls, it uses sh : 当PHP进行系统调用时,它使用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. 但是,使用sh执行virtualenvwrapper.sh脚本失败,所以我们需要使用bash

Another thing to note is that PHP system calls are separate subshells from each other, so if you do: 另外需要注意的是PHP系统调用是彼此独立的子shell,所以如果你这样做:

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

This prints out an empty line. 这打印出一个空行。 Where as the following prints BAR : 以下打印BAR

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

Therefore, we need to: 因此,我们需要:

  • Use bash instead of sh 使用bash而不是sh
  • Source the virtualenvwrapper.sh 来源virtualenvwrapper.sh
  • Execute workon to change working virtual environments 执行workon以更改工作虚拟环境
  • Execute any other commands needed 执行所需的任何其他命令
  • Do all this in one single line 在一行中完成所有这些

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) .'"');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM