PHP exec没有按预期运行我的脚本

时间:2017-04-30 10:48:12

标签: php c linux embedded plc

嘿同事们,

我正在攻读我的学士学位项目,并遇到了一些问题。

目标是创建一个Web应用程序,可以操作和修改WAGO PLC 750-8202(您可以将其视为某种工业Raspberry PI)的I / O运行带有lighttpd Web服务器的嵌入式Linux。我已经制作了一些利用PLC提供的DAL(HAL)功能的C脚本。

现在我想将它与我的网络应用程序/网站链接。我有一个简单的PHP页面(忽略按钮,它什么都不做):

<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <button value="CLICK ME">CLICK ME</button>
<?php
echo system("kbusdemo1");
?>
 </body>
</html>

如您所见,我正在调用kbusdemo1脚本。它应该打印数字输入的值。如果我从连接到我的PLC的SSH终端以root身份调用它,它可以正常工作。但是,如果我从PHP站点调用它(如上所示),它执行但它不显示数字输入值,而是一个错误说&#34;没有在KBUS&#34;上找到设备。您可以在下面的代码中看到确切的行。

KBUS是连接PLC的所有输入/输出模块的总线。基本上看起来它没有正确执行PLC开发人员提供的功能。

这是用C(kbusdemo1.c)

编写的代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>

#include <dal/adi_application_interface.h>

#define KBUS_MAINPRIO 40

int
main(void)
{
    // vars for ADI-interface
    tDeviceInfo deviceList[10];          // the list of devices given by the ADI
    size_t nrDevicesFound;               // number of devices found
    size_t nrKbusFound;                  // position of the kbus in the list
    tDeviceId kbusDeviceId;              // device ID from the ADI
    tApplicationDeviceInterface * adi;   // pointer to the application interface
    uint32_t taskId = 0;                 // task Id
    tApplicationStateChangedEvent event; // var for the event interface of the ADI
    int AnWriteSelect, AnReadSelect, i, j, k, DigWriteOffset = 32, DigReadOffset = 32, vyber;
    int DigWrite[8] = {0}, DigRead[8] = {0};
    char DigWriteBuff[8];
    int16_t AnRead, AnWrite;
    bool loop = false;

    struct sched_param s_param;

    // program start
    //printf("**************************************************\n");
    //printf("***             KBUS test app                  ***\n");
    //printf("**************************************************\n");

    // clear process memory
    memset(DigWrite, 0, sizeof(DigWrite));
    memset(DigWriteBuff, 0, sizeof(DigWriteBuff));
    memset(DigRead, 0, sizeof(DigRead));

    // connect to ADI-interface
    adi = adi_GetApplicationInterface();

    // init interface
    adi->Init();

    // scan devices
    adi->ScanDevices();
    adi->GetDeviceList(sizeof(deviceList), deviceList, &nrDevicesFound);

    // find kbus device
    nrKbusFound = -1;
    for (i = 0; i < nrDevicesFound; ++i)
    {
        if (strcmp(deviceList[i].DeviceName, "libpackbus") == 0)
        {
            nrKbusFound = i;
            printf("KBUS device found as %i\n", i);
        }
    }

    // kbus not found > exit
    if (nrKbusFound == -1)
    {
        printf("No device found on KBUS\n");
        adi->Exit(); // disconnect ADI-Interface
        return -1; // exit program
    }

    // switch to RT Priority
    s_param.sched_priority = KBUS_MAINPRIO;
    sched_setscheduler(0, SCHED_FIFO, &s_param);
    printf("Switch to RT priority 'KBUS_MAINPRIO'\n");

    // open kbus device
    kbusDeviceId = deviceList[nrKbusFound].DeviceId;
    if (adi->OpenDevice(kbusDeviceId) != DAL_SUCCESS)
    {
        printf("Opening KBUS device failed\n");
        adi->Exit(); // disconnect ADI-Interface
        return -2; // exit program
    }
    //printf("Otevření KBUS zařízení OK\n");


    // set application state to "Unconfigured" to let library drive kbus by them selve.
    // In this mode library set up a thread who drive the kbus cyclic.
    event.State = ApplicationState_Unconfigured;   
    if (adi->ApplicationStateChanged(event) != DAL_SUCCESS)
    {
        // Set application state to "Unconfigured" failed
        printf("Setting Unconfigured application state failed\n");  
        adi->CloseDevice(kbusDeviceId); // close kbus device    
        adi->Exit(); // disconnect ADI-Interface        
        return -3; // exit programm
    }
    printf("Unconfigured application state OK\n");

    adi->WatchdogTrigger();
    adi->ReadStart(kbusDeviceId, taskId);
    for (k = 0; k < 8; k++)
    {
            adi->ReadBool(kbusDeviceId,taskId,DigReadOffset,(int*) &DigRead[k]);
        DigReadOffset++;
    }
        adi->ReadEnd(kbusDeviceId, taskId);
    for(k = 0; k < 8; k++)
        printf("%d ",DigRead[k]);
    printf("\n \n");
    DigReadOffset = 32;


    adi->CloseDevice(kbusDeviceId);
    adi->Exit();
    return 0;
}

所以,问题是,我使用的是正确的方法吗? PHP exec适合这种应用吗?如果是这样,任何想法,我做错了什么?

我知道这是设备特定的问题。我目前没有想法,任何可以指向正确方向的提示都是无价的。

感谢您的时间。

修改

好的,我尝试用

编辑sudoers
sudo nano /etc/sudoers

在PLC linux系统中没有实现Visudo。我将其更改为下面发布的代码,但如果我尝试按照您的建议(使用su www)运行它,它仍然无法正常工作。我做错了什么?

谢谢你的建议。

# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the sudoers man page for the details on how to write a sudoers file.
#

# Host alias specification

# User alias specification

# Cmnd alias specification

# Defaults specification

# Runas alias specification

# User privilege specification
root  ALL=(ALL) SETENV: ALL
admin ALL=NOPASSWD: /etc/config-tools/get_user_info
user ALL=NOPASSWD: /etc/config-tools/get_user_info
www ALL=(ALL) NOPASSWD:ALL

# Uncomment to allow people in group wheel to run all commands
# and set environment variables.
# %wheel  ALL=(ALL) SETENV: ALL

# Same thing without a password
# %wheel  ALL=(ALL) NOPASSWD: SETENV: ALL

# Samples
# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users  localhost=/sbin/shutdown -h now

1 个答案:

答案 0 :(得分:0)

如果您以root用户身份运行脚本,则它具有与运行lighthttpd的用户不同的权限。

  • 为用户或群组设置适当的权利(www或www-data,请参阅lighthttpd config)
  • 检查在此用户下运行,在控制台中从root用户切换

    #su - www