命令在命令行上运行,但不通过 Web 服务器运行

命令在命令行上运行,但不通过 Web 服务器运行

注意:跳至“编辑#2”获取新信息 - 我会将原始信息保留在这里,但现在它不太相关了。

我需要一些故障排除帮助——当系统没有给我任何反馈时,这让我很恼火,所以我不知道要寻找什么。

我正在 Linode 上设置一个新服务器:CentOS7、nginx 和 php-fpm。我还有一个本地 VM,其配置应该非常相似。一段 PHP 代码根据数据库数据构建一个文件,将其保存在 tmp 目录中,然后在其上运行命令(uplatex,它在 /usr/local/bin 中有一个符号链接,因此所有用户都应该找到它)以创建其他文件。在我的 VM 上运行良好,但在云服务器上我看不到任何变化 - 没有错误,没有输出。即使我尽力模拟故障情况,它也可以从 SSH 命令行正常运行。我唯一无法模拟的是通过 nginx。

以下是我为了使系统能够给我一些线索而逐步建立起来的故障排除代码:

echo "<html><pre>";
echo "\nMy user (whoami): ";
system('whoami');
echo "\nMy groups: ";
system('groups');
echo "\nMy group right now (id -gn): ";
system('id -gn');
echo "\nIs $tmppath writable [according to PHP itself, not system()/exec()]? ";
echo is_writable($tmppath)?'Yes':'No';
echo "\nIs $tmppath writable [according to a script line in system()]? ";
system("if [ -w $tmppath ] ; then echo 'Yes' ; else echo 'No' ; fi");
echo "\nI'll test writing a file - did it get created? ";
echo system("cd $tmppath;cat \"test\" > dummy.txt");
echo is_file($tmppath.'dummy.txt')?'Yes':'No';
echo "\nWhat is the info about that file?\n";
system("ls -l ".$tmppath."dummy.txt");
echo "\nIs uplatex an executable command to me?\n";
system('command -v uplatex');
echo "\nCan I see the $fileroot.tex file?\n";
system("ls -l $tmppath$fileroot.*");
echo "\nI'm going to try 'cd $tmppath;uplatex $fileroot' now:\n";
system("cd $tmppath;uplatex $fileroot");
echo "Done. There should have been output above this line.\n";
echo "\nDid it create .dvi?\n";
system("ls -l $tmppath$fileroot.*");
echo "</pre><br>\n";

在 Linode 上我得到以下输出:

My user (whoami): www-user

My groups: www-data

My group right now (id -gn): www-data

Is /var/www/tmp/ writable [according to PHP itself, not system()/exec()]? Yes
Is /var/www/tmp/ writable [according to a script line in system()]? Yes

I'll test writing a file - did it get created? Yes
What is the info about that file?
-rw-r--r-- 1 www-user www-data 0 May 12 23:23 /var/www/tmp/dummy.txt

Is uplatex an executable command to me?
/usr/local/bin/uplatex

Can I see the dev-karen-142318.tex file?
-rw-r--r-- 1 www-user www-data 9286 May 12 23:23 /var/www/tmp/dev-karen-142318.tex

I'm going to try 'cd /var/www/tmp/;uplatex dev-karen-142318' now:
Done. There should have been output above this line.

Did it create .dvi?
-rw-r--r-- 1 www-user www-data 9286 May 12 23:23 /var/www/tmp/dev-karen-142318.tex

在我的虚拟机上,我获得了大量对 uplatex 调用的输出(为了简洁,我删掉了大部分内容),生成的文件正如它们应该的那样:

My user (whoami): www-user

My groups: www-data

My group right now (id -gn): www-data

Is /var/www/tmp/ writable [according to PHP itself, not system()/exec()]? Yes
Is /var/www/tmp/ writable [according to a script line in system()]? Yes

I'll test writing a file - did it get created? Yes
What is the info about that file?
-rwxrwxr--. 1 www-data www-data 0 May 12 23:43 /var/www/tmp/dummy.txt

Is uplatex an executable command to me?
/usr/local/bin/uplatex

Can I see the dev-dev-144353.tex file?
-rwxrwxr--. 1 www-data www-data 1286 May 12 23:43 /var/www/tmp/dev-dev-144353.tex

I'm going to try 'cd /var/www/tmp/;uplatex dev-dev-144353' now:
This is e-upTeX, Version 3.14159265-p3.7-u1.21-160201-2.6 (utf8.uptex) (TeX Live 2016) (preloaded format=uplatex)
 restricted \write18 enabled.
entering extended mode
(./dev-dev-144353.tex
pLaTeX2e <2016/11/29u01> (based on LaTeX2e <2016/03/31> patch level 3)
...yada yada...
Output written on dev-dev-144353.dvi (1 page, 952 bytes).
Transcript written on dev-dev-144353.log.
Done. There should have been output above this line.

Did it create .dvi?
-rwxrwxr--. 1 www-data www-data     8 May 12 23:43 /var/www/tmp/dev-dev-144353.aux
-rwxrwxr--. 1 www-data www-data   952 May 12 23:43 /var/www/tmp/dev-dev-144353.dvi
-rwxrwxr--. 1 www-data www-data 12980 May 12 23:43 /var/www/tmp/dev-dev-144353.log
-rwxrwxr--. 1 www-data www-data  1286 May 12 23:43 /var/www/tmp/dev-dev-144353.tex

在 Linode 服务器上的 SSH 中,这是我能最接近模拟故障场景的一次(唯一缺少的层是 nginx 引擎),但它并没有失败:

[root](23:15:10)[/var/www/tmp]$ su www-user
bash-4.2$ whoami
www-user
bash-4.2$ groups
www-user www-data
bash-4.2$ id -gn
www-user
bash-4.2$ ls -la
total 20
drwxr-xr-x 2 www-user www-data 4096 May 12 23:23 .
drwxrwxr-x 7 root     www-data 4096 May 12 12:13 ..
-rw-r--r-- 1 www-user www-data 9286 May 12 23:23 dev-karen-142318.tex
-rw-r--r-- 1 www-user www-data    0 May 12 23:23 dummy.txt
bash-4.2$ uplatex dev-karen-142318
This is e-upTeX, Version 3.14159265-p3.7-u1.21-160201-2.6 (utf8.uptex) (TeX Live 2016) (preloaded format=uplatex)
 restricted \write18 enabled.
entering extended mode
(./dev-karen-142318.tex
pLaTeX2e <2016/11/29u01> (based on LaTeX2e <2017/01/01> patch level 3)
...yada yada...
Output written on dev-karen-142318.dvi (10 pages, 5472 bytes).
Transcript written on dev-karen-142318.log.
bash-4.2$ ls -l
total 40
-rw-r--r-- 1 www-user www-user     8 May 12 23:24 dev-karen-142318.aux
-rw-r--r-- 1 www-user www-user  5472 May 12 23:24 dev-karen-142318.dvi
-rw-r--r-- 1 www-user www-user 12767 May 12 23:24 dev-karen-142318.log
-rw-r--r-- 1 www-user www-data  9286 May 12 23:23 dev-karen-142318.tex
-rw-r--r-- 1 www-user www-data     0 May 12 23:23 dummy.txt
bash-4.2$

我确实注意到用户、组和权限存在一些奇怪的差异,但我无法想象这有什么关系。在我的虚拟机上,虽然whoami说的是 www-user,但创建的文件归 www-data 所有(组也是 www-data)。在 Linode 上,如果我使用 Web 服务器运行我的代码,则用户是 www-user,但组是 www-data。在 SSH 中,su www-user组之后也是 www-user。此外,在我的虚拟机上,新文件的权限为 774,而在 Linode 上则是 644(我更喜欢 644,这应该足够了;我不知道为什么虚拟机如此宽松,但它只是一台开发机器,所以我不在乎)。您可以在上面的输出中看到所有这些内容。但我找不到任何可以阻止 uplatex 运行或创建文件的东西,如果存在权限或访问问题,我会期待出现错误消息 - uplatex 通常非常合群。

有人对要检查什么有什么建议吗?这个 Serverfault 线程听起来很有希望,但我不明白接受的答案与我有什么关系。Linode 上是否有某种秘密安全设置,不喜欢排字员通过网络服务器运行?;-)

编辑以回答评论中的问题...SELinux 是已禁用,输出如下env

XDG_SESSION_ID=5654
HOSTNAME=puphpet2
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=182.165.72.24 58682 22
OLDPWD=/root
SSH_TTY=/dev/pts/1
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin:/root/bin
PWD=/var/www/tmp
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=182.165.72.24 58682 139.162.99.170 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

编辑#2:新信息!我刚刚发现 shell 正在向 stderr 发送错误,而我只查看 stdout。我曾经2>&1重定向它,然后出现了这个错误:

lstat(./euptex) failed ...
./euptex: No such file or directory
euptex: ../../../texk/kpathsea/progname.c:316: remove_dots: Assertion `ret' failed.

但是使用与 PHP 的 system() 函数完全相同的场景(因此用户、shell 等都相同)来测试我能想到的不同事物,我得到了以下结果:

echo $PATH
    /usr/local/bin:/usr/bin
ls -l /usr/local/bin/euptex
    lrwxrwxrwx 1 root root 47 May 12 18:30 /usr/local/bin/euptex -> /usr/local/texlive/2016/bin/x86_64-linux/euptex
whereis euptex
    euptex: /usr/local/bin/euptex
ls -l /usr/local/texlive/2016/bin/x86_64-linux/euptex
    -rwxr-xr-x 1 root root 592016 May 10  2016 /usr/local/texlive/2016/bin/x86_64-linux/euptex
euptex --help 2>&1
    lstat(./euptex) failed ...
    ./euptex: No such file or directory
    euptex: ../../../texk/kpathsea/progname.c:316: remove_dots: Assertion `ret' failed.

如果它在路径中,whereis 可以看到它,并且链接指向一个真实文件,那么为什么 shell 会遇到这么多麻烦?而且我的整个服务器上没有名为 progname.c 的文件,所以我不知道为什么它谈论的是其中的第 316 行。我完全无法理解!

相关内容