Отличается @INC в CGI-скрипте и оболочке

#apache #perl #docker #environment-variables #cgi

#apache #perl #docker #переменные среды #cgi

Вопрос:

У меня есть следующий файл docker-compose:

 version: '2'

services:
    test:
        image: httpd
        container_name: inc_test
        ports:
            - "3000:80"
        environment:
            - PERL5LIB=/somedir
            - PERLLIB=/somedir
        command:
            - bash
            - -c
            - |
                cat /usr/local/apache2/conf/httpd.conf | grep modules/mod_cgid.so
                sed -i 's,#(LoadModule cgid_module modules/mod_cgid.so),1,g' /usr/local/apache2/conf/httpd.conf
                cat /usr/local/apache2/conf/httpd.conf | grep modules/mod_cgid.so
                echo '#!/usr/bin/env perl' >> /usr/local/apache2/cgi-bin/test.pl
                echo 'print "Content-type: text/htmlnn";' >> /usr/local/apache2/cgi-bin/test.pl
                echo 'print join("n", @INC);' >> /usr/local/apache2/cgi-bin/test.pl
                ls -lah /usr/local/apache2/cgi-bin/test.pl
                cat /usr/local/apache2/cgi-bin/test.pl
                httpd -M | grep -e cgid -e alias
                chmod a x /usr/local/apache2/cgi-bin/test.pl
                perl -le 'print for @INC'
                echo "Which perl : "
                which perl
                httpd-foreground
  

Когда я захожу в http://localhost:3000/cgi-bin/test.pl Я вижу, что /somedir этого нет в @INC . Hovewer perl -le 'print for @INC' содержит /somedir .
WTF?

Комментарии:

1. У вас установлено более одной Perl-версии? Вы работаете под разными учетными записями пользователей? Среды не копируются от одного пользователя к другому при разных обстоятельствах. Протестируйте в командной строке с обоими пользователями и посмотрите, есть ли у них одинаковые вещи в @INC

Ответ №1:

После изучения проблемы, которую я обнаружил, проверив, httpd.conf что httpd запускается httpd-foreground под daemon пользователем, а не root.

У пользователя daemon по умолчанию нет shebang:

 $ docker run -it httpd cat /etc/passwd | grep daemon
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
  

Но даже если мы добавим

 runuser - daemon -c "export PERL5LIB=/somedir" -s /bin/bash
  

to command: это не передало бы переменную в perl, поскольку httpd запускает CGI-скрипты в отдельных изолированных процессах, поэтому shell тоже изолирован. Мы можем управлять переменными ENV только с помощью mod_env SetEnv и PassEnv директив.

Итак, для передачи /somedir в @INC нам нужно добавить

 echo "SetEnv PERL5LIB /somedir" >> /usr/local/apache2/conf/httpd.conf