php执行Linux命令的方法(具体案例)

最近本人在做一个系统用来管理团队的任务,其中涉及到我们的任务需要选择项目的git分支,我的方案是利用php去获取某个项目的远程仓库的分支:
exec(“cd /data/www/superb/Git/saint;git pull;git branch -r”, $output);
解释下:
cd /data/www/superb/Git/saint # 跳到从git项目拉下来的代码目录下
git pull  # 更新代码
git branch -r  # 获取当前代码目录下本地和远程所有的代码
一句话执行以上三句需要加上分号。
后来发现git pull无效的问题,即服务器的代码目录并没有自动更新,我获取的远程分支不是最新的。后来发现原来是没有权限,因为git pull这种的写操作无法执行,而git branch这样的读操作是可以执行的。
我的服务器是nginx+php-fpm,最终执行这个linux shell命令的用户是php-fpm的www,使用ps aux | grep php-fpm查看,而且我用php exec执行了whoami:
exec(“whoami”, $output);
也证明了用户是www,于是我将www用户添加到了服务器的sudo列表里:
vim /etc/sudoers
增加一行:
www             ALL=(ALL)       NOPASSWD:ALL
# www             ALL=(ALL)       ALL
下面一行注释掉的和第一行的区别是第一行的配置当www用户在执行sudo操作的时候不需要密码,第二行的配置是所有的sudo操作都要输入www用户的密码。
我把php的代码改成了:
exec(“cd /data/www/superb/Git/saint;sudo git pull;git branch -r”, $output); // git pull用sudo来执行
结果发现依然没有效果,最后我只好用下下策,将/data/www/superb/Git/saint目录和子目录文件的用户和组改为了www:
chown -R www:www  /data/www/superb/Git/saint/
最终php的命令改为:
exec(“cd /data/www/superb/Git/saint;git pull;git branch -r”, $output); // 把sudo去掉
这样就可以执行了,最终实现了我的目标。

修改Linux服务器时间测试crontab

最近在公司做的一个应用,有跟时间有关的逻辑,测试人员需要对这个逻辑进行测试,需要修改Linux服务器的时间,开始的时候,我们使用:

[root@web_test www]# date -s '2013-08-26 9:59'

来修改系统的时间,输入date之后也看到了时间确实被改了,于是我们在等待crontab自动执行10点钟的定时脚本,时间到了之后,我们查看脚本的输出日志,日志的时间或者是日志根本不存在,也就是说脚本根本就没有本执行(我们的脚本手动执行是不会有问题的)。为了排查问题,我们把crontab的中的脚本原来定在10点钟跑的改成了每分钟都会跑,结果是它成功执行了,那么这就说明我们的crontab本身是没有问题的,问题就出在系统时间上了!

查阅了相关的资料发现:在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现。为了保持系统时间与CMOS时间的一致性,Linux每隔一段时间会将系统时间写入CMOS。由于该同步是每隔一段时间(大约是11分钟)进行的,在我们执行date -s后,如果马上重起机器,修改时间就有可能没有被写入CMOS!这就是为什么我们的脚本不执行的问题的原因了。如果要确保修改生效要执行如下命令:

[root@web_test www]# clock -w

修改了系统时间之后再输入clock -w就可以将系统时间写入CMOS,然后我们的crontab定时脚本就跑起来了!

诶,等一下,那我们改了系统的时间怎么把系统的时间还原成现实中的时间呢?不要看着你的手表手动输入,要那种很准确的时间?

我们要做的就是寻找一个网络时间服务器,比如一些国家授时中心,我查了有这些:

微软公司授时主机(美国)
time.windows.com
台警大授时中心(台湾)
asia.pool.ntp.org
中科院授时中心(西安)
210.72.145.44
网通授时中心(北京)
219.158.14.130

我们只要运行:

[root@web_test www]# ntpdate asia.pool.ntp.org

然后再输入clock -w就手动将系统时间写入CMOS,就OK啦!

Linux中less命令常用的参数及用法

我们在使用Linux的时候,阅读很多的手册无法一屏全部显示出来,如果一次全部显示,大部分内容将在你还没来得及阅读的情况下滚出计算机屏幕。通常我们会使用less指令:
[root@localhost ~]# man bash | less
 或者
[root@localhost ~]# less /etc/crontab
 这样就能阅读我们想要看的手册或者文件的内容了,在阅读的时候less还有很多的指令,这里介绍几个常用的指令给大家:
通用指令:
q:退出
h:显示帮助信息
阅读说明书页:
<Space>:显示下一屏
<PageDown>:显示下一屏
f:显示下一屏
<PageUp>:显示上一屏
b:显示上一屏
搜索:
/+你想找的字符:向下搜索你想找的字符模式
?+你想找的字符:向上搜索你想找的字符模式
/+回车:向下查找下一个匹配的文本
n:向下查找下一个匹配的文本
N:向上查找上一个匹配的文本
?+回车:向上查找上一个匹配的文本
在说明书页中移动:
<Return>:向下移动一行
<Down>:向下移动一行
j:向下移动一行
<Up>:向上移动一行
k:向上移动一行
g:移到页的最顶部
G:移到页的最底部

Linux查看用户信息命令whoami,who,w

你可以使用who am i来查看当前用户的标识:

[root@localhost ~]# whoami
root
Linux计算机大多数是共享的,系统可以有多个用户登录,为了查看那些用户登录了,可以使用users:
[root@localhost ~]# users
lijie root
现在是lijie和root处于登录状态。
你还可以使用who来显示用户名、终端的名称以及用户登录时间:
[root@localhost ~]# who
root     pts/0        2012-09-11 22:59 (192.168.0.101)
lijie    pts/1        2012-09-11 23:20 (192.168.0.101)

你如果想看看系统上的用户的更多信息,可以输入w,w的意思是who is doing what?下面的输出的内容:

[root@localhost ~]# w
 23:27:20 up 2 days, 56 min,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.0.101    22:59    0.00s  0.05s  0.00s w
lijie    pts/1    192.168.0.101    23:20    1.00s  0.03s  0.03s -bash
USER是当前登录系统的用户;TTY是各个用户使用的终端的名称;FROM是用户登录系统所使用的远程计算机名称,这里是IP地址;LOGIN@是用户的登录时间;IDLE是用户上一次按键后已经过去的时间;JCPU是用户自从登录后所有进程总共使用的处理器时间,J是job的意思;PCPU是当前进程所使用的处理器时间,P代表process;WHAT是当前正在运行的命令。

Linux查看系统信息指令uptime,hostname,uname

你可以使用uptime指令来查看系统已经运行了多长时间的信息:

[root@localhost ~]# uptime
23:12:03 up 2 days, 40 min,  1 user,  load average: 0.02, 0.02, 0.00
以上信息说明了系统已经运行了2天40分钟,当前有1个用户标识登录,这个用户就是我啦。最后三个数字是一直等待执行的程序的数量,分别是1分钟,5分钟,15分钟的平均数。这些数字能够表示系统的负载,负载越高,系统所做的工作就越多。
hostname用于查看计算机的名称:
[root@localhost ~]# hostname
localhost.localdomain
uname用于显示操作系统的名称:
[root@localhost ~]# uname
Linux
如果想得到操作系统的更多信息,可以使用uname的-a选项,表示all information的意思:
[root@localhost ~]# uname -a
Linux localhost.localdomain 2.6.18-308.13.1.el5 #1 SMP Tue Aug 21 17:10:06 EDT 2012 i686 i686 i386 GNU/Linux
说明我们使用的是Linux内核,版本号是2.6.18-308.13.1.el5。