代码之家  ›  专栏  ›  技术社区  ›  buley

当我的PHP脚本在命令行中运行时,我如何解决它在cron中不工作的问题?

  •  1
  • buley  · 技术社区  · 15 年前

    我有一个脚本调用同一类中的两个函数A和B。a创建了一个Amazon虚拟服务器,b通过Amazon命令行工具的shell exec()销毁了一个。脚本doactions.php从队列中提取操作。如果操作是“创建”,它将创建一个实例;如果操作是“销毁”,它将杀死一个实例。

    当我从命令行php script.php执行脚本时,该脚本可以很好地执行a和b。

    当我把它放在cron上时,它运行,但只成功地运行了b函数。它删除销毁的实例,但不会创建它们。

    故障点显然是功能B。它在第一个也是最重要的shell执行时阻塞,没有返回和回音。

    echo $string = shell_exec('/home/user/public_html/domain.com/private/ec2-api-tools/bin/ec2-run-instances ami-23b6534a -k gsg-keypair -z us-east-1a');
    

    除非您对Amazon命令行工具的工作方式有所了解,否则请向我建议shell_exec在一种情况下而不是在另一种情况下工作的原因。

    同一位置的另一个shell exec的行为与预期一致:

    echo $string = shell_exec ('echo overflow');
    

    我想这是因为它必须与权限有关。但当我运行它时 shell_exec('whoami') 它返回“根”,当我 su 运行命令,它可以正常工作。我很难想出创造性的方法来解决为什么我的php脚本在cron中不能在命令行中工作的问题。你能推荐一些吗?

    1 回复  |  直到 15 年前
        1
  •  3
  •   paxdiablo    15 年前

    当有东西从命令行运行但在 cron ,这通常是一个环境问题(路径或运行的代码所需的其他环境变量)。

    首先,您应该修改脚本以输出当前环境( shell_exec('env') ?)在最上面,检查命令行和cron的输出。

    希望会有一些明显的东西,比如 AMAZON_EC2_VITAL_VAR 但是,如果没有,您应该将cron环境移向命令行1,一次一个变量,直到它开始工作。

    一个快速的测试来确定这一点。从命令行执行以下操作:

    env >/tmp/pax_env.sh
    

    然后从首先执行的shell脚本运行php脚本:

    . /tmp/pax_env.sh
    

    这样环境就相同了。

    记住 su 它本身并不能为您提供与作为特定用户直接登录所获得的环境相同的环境。( su - 是的,我 认为 )您可能需要检查作为根用户直接登录时的行为。


    回复您的评论:

    是的,我相信你知道。我可能会把你的答案标记为正确的,但需要你对你的聪明的解决方案做一些补充。首先,执行pax-env.sh脚本的最佳方法是什么?shell exec()工作吗?

    别让别人说我不是为钱工作的。—)不。是的。 shell_exec 几乎肯定会运行一个子shell,以便设置变量 在里面 但不会影响PHP父进程。

    我的建议是,如果您希望设置所有这些变量,那么应该创建一个shell脚本,其中包含 /tmp/pax_env.sh (可能在每一个 export )然后是当前正在运行的命令 克朗 沿着以下几条线:

    export PATH=.:/usr/bin
    export PS1=Urk:
    export PS2=MoreUrk:
    /home/user/pax/scriptB.php
    

    然后运行 那个 脚本从 克朗 而不是 /home/user/pax/scriptB.php 直接。这将确保在调用PHP代码之前设置环境。

    精明的读者会注意到上面的短语“如果你想设置所有这些变量”。我个人不认为这是个好主意 全部的 将命令行变量放入 克朗 工作。我更愿意找出哪些是需要的,只包括那些。这就减少了你的同事工作所面临的污染。例如,不太可能 PS1/PS2 PHP脚本需要提示变量。

    如果它起作用,你 可以 设置所有的环境变量-我只喜欢绝对最小值,这样当事情发生变化时就不必担心太多。

    找出需要做什么的一种方法是评论 出口 直到脚本再次中断。然后你知道变量是必需的。一旦达到最大值 出口 声明被注释掉了,你可以完全删除那些被注释的导出声明,剩下的,无论多么不可能,都必须是好的(向阿瑟·柯南·道尔爵士道歉)。