簡體   English   中英

你如何從PHP exec調用python命令“workon”?

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

我正在從CLI運行PHP腳本。 在那個PHP腳本中,我想使用system()從命令行執行一些命令。 也許這不是適合這項工作的工具,我可能只是將PHP腳本包裝在shell腳本中,但我想知道是否可以在PHP腳本中完全完成。

當我在終端中執行此操作時,它可以正常工作:

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 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="$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

我通過安裝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功能,我們首先需要sourcevirtualenvwrapper.sh文件。 要查找該文件的位置,請在終端執行:

which virtualenvwrapper.sh

如果這不產生任何輸出,請使用find來查找它。

find /usr/ -name "virtualenvwrapper.sh"

對我來說,位置是/usr/local/bin/virtualenvwrapper.sh

當PHP進行系統調用時,它使用sh

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

但是,使用sh執行virtualenvwrapper.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) .'"');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM