在尝试确定.bashrc
和之间的差异时,.bash_profile
我注意到.bashrc
从未读取过,并且.bash_profile
仅从 SSH 读取,而不是从 PHP 读取。这似乎与 中的信息相矛盾man bash
。有人可以向我解释一下为什么会这样吗?该服务器似乎是 CentOS 5 变体。
local$ ssh user@server
Last login: Wed Jan 23 23:21:23 2013 from 1.2.3.4
$ cat .bashrc
alias br='echo fromBR'
$ cat .bash_profile
alias bp='echo fromBP'
$ br
-bash: br: command not found
$ bp
fromBP
$ cat public_html/bashtest.php
<?php
echo "hello\n";
echo shell_exec('bp');
echo shell_exec('br');
?>
$ php public_html/bashtest.php
hello
sh: bp: command not found
sh: br: command not found
$ wget server/bashtest.php
23:35:13 (759.55 KB/s) - `bashtest.php' saved [7/7]
$ cat bashtest.php
hello!
所以看起来它.bashrc
永远不会被读取,.bash_profile
只能从 CLI 读取(不是从用户 CLI 上的 PHP 读取,也不是通过 Apache 读取)。此外,通过 Apache,“未找到命令”文本甚至不会返回!
这是预期的行为(即我误解了man bash
)还是出了什么问题?
答案1
好吧,首先,PHP 并没有在你的例子中完成shell_exec
,bash
它是通过sh
.从确切的错误消息来看,这一点相当明显。我是猜测这是由在 /etc/passwd 中为 Web 服务器运行的用户指定的任何 shell 控制的,并且 shell_exec 不会捕获 stderr,与此相结合,当您从命令行运行 PHP 时,它只是退出到 $ {壳}。当作为 sh 启动时,bash 会关闭许多功能以更好地模仿原始 sh shell 的行为。如果没有其他原因,.bashrc
几乎可以肯定的是,这些文件的来源.bash_profile
是其中之一,因为这些文件可能使用特定于 bash 的语法或扩展。
我不太确定 SSH 的情况,但从简单的$
提示来看,您很可能正在那里运行 sh,这同样可以解释您所看到的行为。试着echo ${SHELL}
看看你真正陷入了什么;这应该适用于所有 shell。
那就是说,在我看来,依赖 PHP 脚本中的 bash 别名是一个非常糟糕的主意。如果您想要做的事情太长而无法很好地适合语句shell_exec
本身(只能非常小心地使用),那么创建一个 PHP 函数来从参数创建命令行并调用它几乎肯定是一个更好的方法,它基本上会起作用不管安装、选择哪个 shell 或如何配置它。或者,考虑调用外部脚本文件,该文件可以用 bash 编写并指定 /bin/bash 作为其解释器。但是你的应用程序将要求安装 bash(如果它依赖于 bash 别名,它可能已经安装了......)。