Различный @INC в CGI скрипте и оболочке - PullRequest
0 голосов
/ 21 марта 2019

У меня есть следующий файл 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/html\n\n";' >> /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 Ответ

1 голос
/ 21 марта 2019

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

Пользователь daemon не имеет шебанга по умолчанию:

$ 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
С

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

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

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