简体   繁体   English

外壳脚本中的sudo命令,由PHP调用

[英]sudo command inside shell script and called by PHP

Background 背景

I have made a PHP web application to execute a Linux Shell Script to change the data in network-scripts of CentOS 7. In other words, this is a PHP web application that can change the IP in CentOS 7. 我已经制作了一个PHP Web应用程序来执行Linux Shell脚本,以更改CentOS 7的网络脚本中的数据。换句话说,这是一个可以更改CentOS 7中IP的PHP Web应用程序。

The script itself is good to change, I can run the script using SSH with proper arguments, the usage like the following: 脚本本身很容易更改,我可以使用带有适当参数的SSH运行脚本,用法如下:

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

Sample usage: 用法示例:

 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

That will change the IP from 192.168.1.5 to 192.168.1.205 and the subnet mask will be changed from 255.255.255.255 to 255.255.255.0 . 这样会将IP从192.168.1.5更改为192.168.1.205 ,并将子网掩码从255.255.255.255更改为255.255.255.0 The gateway will remain unchanged. 网关将保持不变。


PHP Application PHP应用

The data will be posted from a form processed with PHP. 数据将从使用PHP处理的表单中发布。 The code will check if the IP addresses are correct or not. 该代码将检查IP地址是否正确。 If the arguments are collected and correct, my PHP code will call the shell script to make changes to the network-scripts. 如果参数被收集并且正确,我的PHP代码将调用Shell脚本来更改网络脚本。

Like this: 像这样:

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

That means: 这意味着:

$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');


Shell Scripts Shell脚本

#!/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}`


Problem 问题

The file /etc/sysconfig/network-scripts/ifcfg-ens32 doesn't changed at all. 文件/etc/sysconfig/network-scripts/ifcfg-ens32完全没有更改。 If I run the shell script in SSH (refer to sample usage in background chapter), it works! 如果我在SSH中运行shell脚本(请参阅背景章节中的示例用法),则可以正常工作! So my shell script should be fine. 所以我的shell脚本应该没问题。


Other Trials 其他试用

1. Put echo in shell script to see if the arguments are in the correct position 1.将echo放入shell脚本中,以查看参数是否在正确的位置
Result: Yes. 结果:是的。
The arguments showed just like expected. 参数显示出与预期的一样。

2. Put 2>&1 behind the exec() 2.将2>&1放在exec()后面
Result: Message showed. 结果:显示消息。
sudo: sorry, you must have a tty to run sudo . sudo: sorry, you must have a tty to run sudo I don't know if sed needs root permission or not. 我不知道sed需要root权限。 So I put it in the shell script anyway to make the shell script execute smoother. 因此,无论如何,我将其放在Shell脚本中以使Shell脚本执行起来更加流畅。

3. Remove sudo in shell script 3.在shell脚本中删除sudo
Result: In SSH, good; 结果:在SSH中,很好; In PHP, message showed. 在PHP中,显示消息。
sed: couldn't open temporary file /etc/sysconfig/network-scripts/sedJfDtCD: Permission denied . sed: couldn't open temporary file /etc/sysconfig/network-scripts/sedJfDtCD: Permission denied I googled this message. 我用谷歌搜索了此消息。 When using sed -i , it will create a temporary file to store the original file in case the script messed up. 使用sed -i ,它将创建一个临时文件来存储原始文件,以防脚本混乱。

4. Remove -i in sed command in shell script 4.在shell脚本中的sed命令中删除-i
Result: Failed. 结果:失败。
The script cannot perform its task. 该脚本无法执行其任务。


Other Information 其他资讯

  • OS: CentOS 操作系统: CentOS
  • Web server type: LAMP Web服务器类型: LAMP
  • whoami: apache whoami:阿帕奇
  • Script usage: Internal use. 脚本用法:内部使用。 So I don't care about security issues 所以我不在乎安全性问题
  • Please help! 请帮忙! Thanks. 谢谢。

    not directly for you right problem but i advice to add some security on such file change 不直接为您解决问题,但我建议为此类文件更改添加一些安全性

    and optimize the three last lines with: 并使用以下命令优化最后三行:

    `sudo sed -i -e "s/$currentIpAddress/$newIpAddress/g;s/$currentSubnetMask}/$newSubnetMask/g;s/$currentGateway/$newGateway/g" ${fileName}`
    
    • the last g of each of your s/// is normaly not necessary (only 1 change by line) 通常不需要每个s///的最后一个g (仅一行更改1个)

    I recently published a project that allows PHP to obtain and interact with a real Bash shell (as user: apache/www-data or root if needed). 我最近发布了一个项目,该项目使PHP可以获取真实的Bash shell并与之交互(作为用户:apache / www-data或root(如果需要))。 Get it here: https://github.com/merlinthemagic/MTS 在这里获取它: https : //github.com/merlinthemagic/MTS

    After downloading you would simply use the following code. 下载后,您只需使用以下代码。

    //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);
    

    After the config file change you can then reload the interface config using the same shell: 更改配置文件后,您可以使用相同的Shell重新加载接口配置:

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

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM