Nginx的if匹配变量和字符串相等时,如果变量内容带换行符(较常见情况是变量由lua从文件中获取的字符串), 那么使用=则不会匹配

文件

[root@erica vhosts]# cat /tmp/tmp.txt 
123 cn
456 bb

直接使用if = 号匹配

nginx配置

server {
    listen 8088;
    index index.html index.htm index.php;
    root  html;
    default_type 'text/html';

    location  / {
        set_by_lua $address '
             local s = "123";
             local j = io.popen("grep " ..s.. " /tmp/tmp.txt|awk \'{print $2}\'");
             j = j:read("*all");
            return j;
        ';

        if ($address = cn){
                return 200 'match cn';
        }

        return 200 $address;
    }
}

请求结果

[root@erica vhosts]# curl http://127.0.0.1:8088
cn

打印到网页能看到是cn, 但是if匹配不到,猜想可能cn字符串后面带有换行符

直接用lua return一个字符串,再次尝试

在set_by_lua中直接return "cn"

server {
    listen 8088;
    index index.html index.htm index.php;
    root  html;
    default_type 'text/html';

    location  / {
        set_by_lua $address '
             local s = "123";
             local j = io.popen("grep " ..s.. " /tmp/tmp.txt|awk \'{print $2}\'");
             j = j:read("*all");
            return "cn";
        ';

        if ($address = cn){
                return 200 'match cn';
        }

        return 200 $address;
    }
}
[root@erica vhosts]# curl http://127.0.0.1:8088
match cn[root@erica vhosts]# 

if = 号匹配到了字符串cn

如何匹配有换行符的字符串?

使用正则匹配~,不使用=

server {
    listen 8088;
    index index.html index.htm index.php;
    root  html;
    default_type 'text/html';

    location  / {
        set_by_lua $address '
             local s = "123";
             local j = io.popen("grep " ..s.. " /tmp/tmp.txt|awk \'{print $2}\'");
             j = j:read("*all");
            return j;
        ';

        if ($address ~ "^cn$"){
                return 200 'match cn';
        }

        return 200 $address;
    }
}
[root@erica vhosts]# curl http://127.0.0.1:8088
match cn[root@erica vhosts]# 

思考,为什么通过awk取出来的字段会带换行符?

awk其实取到的不带换行符,主要是j = j:read("*all"); 这步是从文件中读取的内容

下面我试着不读取全部文件内容,读取文件前两个字节,也就是cn字符串 => j = j:read(2);

server {
    listen 8088;
    index index.html index.htm index.php;
    root  html;
    default_type 'text/html';

    location  / {
        set_by_lua $address '
             local s = "123";
             local j = io.popen("grep " ..s.. " /tmp/tmp.txt|awk \'{print $2}\'");
             j = j:read(2);
            return j;
        ';

        if ($address = cn){
                return 200 'match cn';
        }

        return 200 $address;
    }
}

[root@erica vhosts]# curl http://127.0.0.1:8088
match cn[root@erica vhosts]# 

这样就能匹配到了

最后修改:2020 年 01 月 15 日
如果觉得我的文章对你有用,请随意赞赏