最近在做php和linux crontab的联调,发现php在linux下的权限问题需要引起注意,调试问题的过程中发现有许多问题前人说的比较零散,我在这里汇总,顺带抛砖引玉一下。

1、$result=system($cmd,$return_status)需要区分返回值与返回状态。返回值是$cmd执行后返回执行结果的最后一行,而$return_status是返回状态,比如$cmd是crontab一个计划任务,若Linux执行成功,则返回0(详见Linux条件测试)给$return_status,故在PHP端看到$return_status变为0;若执行的是ls,则PHP端看$return_status是一串字符(很可能是乱码)。

2、路径所涉及的权限问题会导致system()看起来无效(命令执行后Linux没反应),其实主要观察返回状态即可,如system($cmd,$return_status),$return_status返回状态这里要小心,因为它是来自linux的消息,返回了0代表执行成功,1代表执行失败。所以,PHP配合linux时,涉及到路径的都应该仔细考虑一下是否有权限,特别是返回状态为1的时候。

3、往某目录A下增删文件,只要目录A有w权限,相应的用户就能增删,比如PHP在linux看来属于其他用户(www-data这个用户组),若将目录A的其他用户w权限关闭,则无法在该目录下创建文件,可以通过sudo,但是一定要保证PHP有使用sudo的权限(见第4条),否则也是无法创建的。而且能否往A中写只与A的权限有关,与A的父目录B有无w权限无直接关系。顺带提醒一下,php调用linux命令创建文件时,文件名应该转义,如 $cmd='touch /home/pi/`date +\%m_\%d_\%H_\%M.txt`'; system($cmd);  否则会遇到一切看起来都正常,但是就是没文件被创建的问题,因为不转义,Linux无法识别文件名中的符号。

4、PHP调用Linux命令是以www-data这个用户组身份进行的,这个用户组的默认权限特别低,以至于用system()涉及sudo等需要密码的命令都无法执行。解决方法可以命令行输入sudo visudo打开sudoers.tmp,在这里面添加“www-data ALL=(ALL) NOPASSWD: ALL”(或者在/etc/sudoers.d/下新建一个660权限的文件,并添加此句命令,虽然系统会自动把权限改回440,为了方便写入,这里还是新建一个660的文件),这样www-data这个用户组(即PHP)执行Linux的sudo命令就没有问题了。

5、所有正在运行crontab计划的用户在/var/spool/cron/crontabs目录下可以看到(目录名大同小异吧,都是在/var/spool/cron/下)。命令行中直接crontab的话,是添加root的任务计划,需要su后crontab -l才能看到;直接crontab -l看到只是当前用户的计划任务。crontab -u -user 可以指定某个用户的任务计划,当php取得sudo权限后,就可以为linux下其他用户定制crontab了。

小结:php和linux联调,我发现遇到的问题主要是权限,所以不能实现功能时,先检查权限是否得到满足,比如php的www-data处于何种权限,要写入的目录处于何种权限等;当权限疏导好后,用system()执行linux命令还是很方便的。

原创博客,如有错误,欢迎指正。

php通过system()调用Linux命令问题的更多相关文章

  1. scala调用Linux命令行

    在 scala 里面存在 调用 Linux 命令行的函数: import scala.sys.process._ 执行的方法也不难: import scala.sys.process._ /** * ...

  2. Spark调用Linux命令实现解压和压缩功能

    一.应用场景 在Spark程序中调用Linux命令,实现一些程序难以实现的功能,例如:发送模拟邮件.文件打包或解压等等 二.代码实现 package big.data.analyse.linux im ...

  3. Java调用Linux命令执行

    调用方式 Java调用linux命令执行的方式有两种,一种是直接调用linux命令,一种是将linux命令写到.sh脚本中,然后调用脚本执行. 详细说明 直接调用:使用java中lang包下面的Run ...

  4. Java调用Linux命令(cd的处理)

    一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: public String executeLinuxCmd(String cmd) { System.out.print ...

  5. java调用Linux命令报错:java.io.IOException: Cannot run program "ps": CreateProcess error=2, ?????????

    在idea里面,java代码:Runtime.getRuntime().exec("ps -aux") 是因为默认是用windows平台运行了,所以报错,得改成调用Linux平台运 ...

  6. 如何在java程序中调用linux命令或者shell脚本

    转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...

  7. java程序中调用Linux命令Windows命令

    目前总结的方法: 调用Linux简单的命令行,设置文件夹权限755 String scriptDir = "/home/wenf"; String cmd = "chmo ...

  8. jsch ssh服务器调用Linux命令或脚本的小问题

    代码如下: public static boolean execshell(String command, String user, String passwd, String host) throw ...

  9. Python中如何调用Linux命令

    一.使用os模块 In [1]: import os #导入os模块 In [2]: os.system('ls') anaconda-ks.cfg epel-release-7-5.noarch.r ...

随机推荐

  1. 小随笔:利用Shader给斯坦福兔子长毛和实现雪地效果

    0x00 前言 发现最近没有了写长篇大论的激情,可能是到了冬天了吧.所以这篇小文只是简单介绍下如何在Unity中利用shader很简单的实现雪地效果以及毛皮效果,当然虽然标题写在了一起,但其实这是俩事 ...

  2. POJ1082食物链

    加权并查集入门习题. 传送门http://poj.org/problem?id=1182 下面来记录一下做法: 并查集的作用是询问两个对象时候在同一集合以及将两个非空不相交集合合并. 本题涉及两点之间 ...

  3. MS08_067漏洞学习研究

    p197 MS08-067漏洞渗透攻击 按照书上的设置做,exploit得到错误信息: Exploit failed [unreachable]: Rex::ConnectionRefused The ...

  4. windows下安装和redis主从配置(通过哨兵控制主从切换)

    首先自己先得了解什么是redis,这里就不详做介绍什么是redis了,这篇文章主要讲的是怎么样配置 redis怎样配置主从关系和哨兵控制主从服务器的配置以及应用,就当是给自己记笔记吧! 1.下载red ...

  5. JQuery之事件冒泡

    JQuery 提供了两种方式来阻止事件冒泡. 方法一:event.stopPropagation(); $("#div1").mousedown(function(event){  ...

  6. JAVA基础5——与String相关的系列(2)

    差异点比较 String使用+直接拼接 这种情况需要分两种情况来讨论: 1. 都是确定的字符串常量之间进行的+号拼接的时候,由于在编译器就可以确定其具体值了,所以编译器在编译期的时候就会把这些常量拼接 ...

  7. springboot-helloworld

    1使用idea创建springboot项目如下图所示 并选择web模块 2,登录springboot官网 http://projects.spring.io/spring-boot/ 引入相关依赖包如 ...

  8. [C#]使用Gembox.SpreadSheet向Excel写入数据及图表

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...

  9. Java爬虫实践--爬取CSDN网站图片为例

    实现的效果,自动在工程下创建Pictures文件夹,根据网站URL爬取图片,层层获取.在Pictures下以网站的层级URL命名文件夹,用来装该层URL下的图片.同时将文件名,路径,URL插入数据库, ...

  10. Scala入门系列(五):面向对象之类

    定义类 // 定义类,包含field以及method class HelloWorld { private var name = "Leo" def sayHello() { pr ...