shell脚本中的sudo命令,并由PHP调用


sudo command inside shell script and called by PHP

背景

我制作了一个PHP web应用程序来执行Linux Shell脚本,以更改CentOS7的网络脚本中的数据。换句话说,这是一个PHP web应用程序,可以在Centos7中更改IP。

脚本本身很好更改,我可以使用带有适当参数的SSH运行脚本,用法如下:

sh ./ipchanger.sh <fileName> <oldIpAddress> <newIpAddress> <oldSubnetMask> <newSubnetMask> <oldGateway> <newGateway>

示例用法:

 sh ./ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1

这将把IP从192.168.1.5更改为192.168.1.205,并且子网掩码将从255.255.255.255更改为255.255.255.0。网关将保持不变。


PHP应用程序

数据将从用PHP处理的表单中发布。该代码将检查IP地址是否正确。如果参数被收集并正确,我的PHP代码将调用shell脚本来更改网络脚本。

像这样:

$retval = exec('sh /var/www/html/ipchanger/ipchanger.sh {$fileName} {$currentIpAddress} {$newIpAddress} {$currentSubnetMask} {$newSubnetMask} {$currentGateway} {$newGateway}');

这意味着:

$retval = exec('sh /var/www/html/ipchanger/ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1');


外壳脚本

#!/bin/sh
#
# My IP Changer
fileName="$1"
currentIpAddress="$2"
newIpAddress="$3"
currentSubnetMask="$4"
newSubnetMask="$5"
currentGateway="$6"
newGateway="$7"
`sudo sed -i -e "s/$currentIpAddress/$newIpAddress/g" ${fileName}`
`sudo sed -i -e "s/$currentSubnetMask}/$newSubnetMask/g" ${fileName}`
`sudo sed -i -e "s/$currentGateway/$newGateway/g" ${fileName}`


问题

文件/etc/sysconfig/network-scripts/ifcfg-ens32根本没有更改。如果我在SSH中运行shell脚本(请参阅背景章节中的示例用法(,它就可以工作了!所以我的shell脚本应该很好。


其他试验

1.在shell脚本中放入echo以查看参数是否位于正确的位置
结果:是
争论的结果和预料的一样。

2.放入2>&exec后面的1((
结果:显示消息
sudo: sorry, you must have a tty to run sudo。我不知道sed是否需要root权限。所以我还是把它放在shell脚本中,以使shell脚本执行得更流畅。

3.在shell脚本中删除sudo
结果:在SSH中,良好;在PHP中,消息显示
sed: couldn't open temporary file /etc/sysconfig/network-scripts/sedJfDtCD: Permission denied。我在谷歌上搜索了这条消息。当使用sed -i时,它会创建一个临时文件来存储原始文件,以防脚本出错。

4.在shell脚本的sed命令中删除-i
结果:失败
脚本无法执行其任务。


其他信息

  • 操作系统:可在
  • Web服务器类型:LAMP
  • whoami:apache
  • 脚本使用:内部使用。所以我不关心安全问题
  • 请帮忙!谢谢

    不是直接针对你的正确问题,但我建议在这样的文件更改上添加一些安全性

    并优化最后三行:

    `sudo sed -i -e "s/$currentIpAddress/$newIpAddress/g;s/$currentSubnetMask}/$newSubnetMask/g;s/$currentGateway/$newGateway/g" ${fileName}`
    
    • 每个s///的最后一个g是正常的,没有必要(只需一行更改(

    我最近发布了一个项目,该项目允许PHP获得真正的Bash shell并与之交互(如果需要,可以作为用户:apache/www-data或root(。在这里获取:https://github.com/merlinthemagic/MTS

    下载后,您只需使用以下代码。

    //You could maintain your ipchanger.sh script and simply trigger that script
    //through the shell, but the point of the shell project is that it lets you 
    //trigger commands directly. in your case you could do this:
    $ifFilePath = '/etc/sysconfig/network-scripts/ifcfg-ens32';    
    $ifCfg= "DEVICE=ens32";
    $ifCfg.= "'nIPADDR=192.168.1.205";
    $ifCfg.= "'nPREFIX0=24";
    $ifCfg.= "'n192.168.1.1";
    $strCmd = "echo ''".$ifCfg."'' > ''".$ifFilePath."''";
    //But if you wanna stick with your script then:
    $strCmd = "sh ./ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1";
    //in either case the $strCmd is triggered like this:
    $shell    = 'MTS'Factories::getDevices()->getLocalHost()->getShell('bash', true);
    $return1  = $shell->exeCmd($strCmd);
    

    配置文件更改后,您可以使用相同的shell重新加载接口配置:

    $return2  = $shell->exeCmd('service network restart');