PHP脚本赢得';不要在命令行上运行

PHP脚本赢得';不要在命令行上运行,php,command-line-interface,daemon,gremlin,Php,Command Line Interface,Daemon,Gremlin,守则: #!/usr/bin/php -q <?php while(true){ $rate_limit = json_decode(file_get_contents('http://api.twitter.com/1/account/rate_limit_status.json'),true); # Check how many API calls remain $wait = round(3600/150); # *** IMPORTANT ***

守则:

#!/usr/bin/php -q
<?php
while(true){
    $rate_limit = json_decode(file_get_contents('http://api.twitter.com/1/account/rate_limit_status.json'),true); # Check how many API calls remain

    $wait = round(3600/150);
    # *** IMPORTANT ***
    # Twitter limits API calls to 150/hr so regardless of the number of handles, we can only make one request every 24 seconds (which is 3600/150).
    # As a result, it takes one hour to run through 150 handles one time each.  Since we'll probably never monitor that many, each handle may get updated multiple times an hour.

    # Establish the database connection
    if(!$mysqli = mysqli_connect('localhost','twitterd','password','twitterd')){
        file_put_contents('tweet_gremlin.log', date('r') . ' Cannot connect to the database');
        break;
    }

    $get_handles = mysqli_query($mysqli,"SELECT `handle` FROM twitter_handles"); # Grab the Twitter handles from the database

    #  Append them to the $handles array
    while($row = mysqli_fetch_array($get_handles,MYSQLI_NUM)){
        $handles[] = $row[0];
    }

    #  Check the remaining API calls
    if($rate_limit['remaining_hits']<count($handles)){
        file_put_contents('tweet_gremlin.log', date('r') . ' Rate limit reached', FILE_APPEND);
        sleep(600);
        continue;
    }else{
        # Loop through the $handles values, make an API call, and insert the tweets.
        foreach($handles as $value){
            file_put_contents('tweet_gremlin.log', date('r') . ' Processing ' . $value . '\'s data...' . PHP_EOL, FILE_APPEND); # Tell the log what we're doing

            $user_data = json_decode(file_get_contents('http://search.twitter.com/search.json?q=from:' . $value . '&rpp=100&include_entities=1'),true); # Get the handle's timeline and put it into $user_data
            $user_data = $user_data['results']; # Put only the results index (tweets) into into $user_data

            if(count($user_data)<1){
                file_put_contents('tweet_gremlin.log', date('r') . ' No data for ' . $value . PHP_EOL, FILE_APPEND);
            }

            for($i=0;$i<count($user_data);$i++){
                # Lazy method for sanitizing variables
                $id = mysqli_real_escape_string($mysqli,$user_data[$i]['id']);
                $created_at = mysqli_real_escape_string($mysqli,$user_data[$i]['created_at']);
                $from_user_id = mysqli_real_escape_string($mysqli,$user_data[$i]['from_user_id']);
                $profile_image_url = mysqli_real_escape_string($mysqli,$user_data[$i]['profile_image_url']);
                $from_user = mysqli_real_escape_string($mysqli,$user_data[$i]['from_user']);
                $from_user_name = mysqli_real_escape_string($mysqli,$user_data[$i]['from_user_name']);
                $text = mysqli_real_escape_string($mysqli,$user_data[$i]['text']);

                $needles = array('hack','tango down','dump','breach','data');

                # Check the tweet relevance
                foreach($needles as $needle){
                    $needle = '/' . $needle . '/i'; # So we don't have to manually type out the regex

                    # Make a call based on the tweet contents
                    if(preg_match($needle,$text) == 0){
                        file_put_contents('tweet_gremlin.log', date('r') . ' No relevant tweet data in tweet #' . $id .PHP_EOL, FILE_APPEND);
                    }else{
                        file_put_contents('tweet_gremlin.log', date('r') . ' Processing tweet #' . $id .PHP_EOL, FILE_APPEND);
                        $insert_tweets = "INSERT INTO tweets (`id`,`created_at`,`from_user_id`,`profile_image`,`from_user`,`from_user_name`,`text`) VALUES ('{$id}','{$created_at}','{$from_user_id}','{$profile_image_url}','{$from_user}','{$from_user_name}','{$text}');";
                        mysqli_query($mysqli,$insert_tweets);
                    }
                }
            }
            file_put_contents('tweet_gremlin.log', date('r') . ' Sleeping for ' . $wait . ' seconds before processing the next handle' .PHP_EOL, FILE_APPEND);
            sleep($wait);
        }
    }
    mysqli_close($mysqli);
}
?>
它运行良好。但如果我像这样运行它:

./tweet_gremlin.php
./tweet_gremlin.php &
它什么也不做。我不明白为什么


编辑:我必须拿出几乎所有的代码,因为它不允许我提交所有的代码。

你用符号创建了一个后台作业

根据底层操作系统的不同,后台作业将更改为“已停止”状态,因为它希望从标准输入读取和/或写入标准输出

启动
/tweet\u gremlin.php&

这会告诉你的工作状态

如果作业的状态为“已停止”,则放弃STDOUT+STDERR和STDIN:
/tweet\u gremlin.php/dev/null&

如果您的脚本现在运行,您需要在
/tweet\u gremlin.php&

例如,写入日志文件而不是STDOUT+STDERR

您还可以测试终端的行为。
由于缺少分号,下面在STDERR上创建了一个PHP错误:

php -r 'echo "backgrounding sucks\n"' &
jobs
fg1
以下内容在标准输出上创建正常输出:

php -r 'echo "backgrounding sucks\n";' &
jobs
fg1

如果无法解决代码中的问题,请查看终端的设置。当心stty tostop(信号)

当你说“它什么也不做”时,你是什么意思?您是否在命令行上执行了
ps
,以验证它是否未运行?
&
告诉终端在后台运行该进程,如果您想启动多个GUI驱动的程序,这会很有帮助,但如果您正在运行PHP脚本,则不会有多大帮助。尝试运行:
PHP./tweet\u gremlin.PHP
符号(&)表示在后台运行任务。现在,如果它提示输入,它将阻塞并停止运行,直到您将其带到前台。在第二种情况下,您可以将进程启动到后台。您确定它没有运行吗?它在后台运行,但不执行while()循环中的任何代码。它不需要任何用户输入。这非常有用。我运行了您的测试,运行时。/tweet_gremlin.php&作业确实停止了。如果我在脚本
error\u reporting(E\u ALL)
error\u log(E\u ALL,3,“tweet\u gremlin.log”)
中设置了错误报告(E\u ALL),这将减轻以
/tweet\u gremlin.php/dev/null&
的形式运行脚本的需要吗?目标是不在STDOUT和STDERR上生成任何输出。我对PHP CLI的了解还不够深入,无法说明如何实现这一点。你需要调查你自己。error_log()只处理一条单独的错误消息。但您需要处理所有错误消息和异常。set\u error\u handler()可能是一个起点。或者通过设置error_reporting 0并捕获所有异常来完全抑制错误。他,他stackoverflow来拯救:在PHP中描述了重定向STD*,这就是方法!唯一的缺点是,它只能在类似Unix的操作系统上运行。但是嘿。。。