所以使用'php index.php'在命令行中给出了我想要的输出。但是不会在网页上给出输出。 首先,我有这个python文件基本上可以做我想要的一切:
import subprocess
subprocess.call("sudo nmap -sP 192.168.1.0/24 > /home/pi/whohome.txt", shell=True)
searchfile = open("/home/pi/whohome.txt", "r")
for line in searchfile:
if "android-5ab6eb374b5fd6" in line: print "Jeremy is home (phone)"
if "Jeremys-MBP" in line: print "Jeremy is home (computer)"
if "LMCMs-iPhone" in line: print "Liam is home (phone)"
if "Liam" in line: print "Liam is home (computer)"
if "android-4a186cbbeb2c5229" in line: print "Lara is home (phone)"
if "LaraD" in line: print "Lara is home (computer)"
if "KristiansiPhone" in line: print "Martin is home (phone)"
if "Martins-MBP" in line: print "Martin is home (computer)"
searchfile.close()
其次我只有一个sh可执行文件,它将把这个python命令的输出放到另一个文本文件中:
python /home/pi/myRoomMates.py > /var/www/html/website.txt
然后我在一个运行在raspberry pi上的apache web服务器上安装了php文件,它显示为:
<?php
shell_exec('/home/pi/whoishome.sh');
echo file_get_contents ("/var/www/html/website.txt");
?>
所以,如果我没有错,每次刷新页面时都应执行该操作,等待exec完成,然后显示txt文件内容?我已经尝试了shell_exec和exec,它们都做同样的事情。
答案 0 :(得分:1)
有很多权利,你必须确保:
/home/pi/whohome.txt
/var/www/html/website.txt
/home/pi/whoishome.sh
必须是apache用户的可执行文件对于第1点到第3点,给apache用户这些权利通常不是一个好主意。
如果以Python CGI开始你的python脚本,你可以更轻松:
import subprocess
ADDRESS = "192.168.1.0/24"
USERS = {
"android-5ab6eb374b5fd6": ("Jeremy", "phone"),
"Jeremys-MBP": ("Jeremy", "computer"),
"LMCMs-iPhone": ("Liam", "phone"),
"Liam": ("Liam", "computer"),
"android-4a186cbbeb2c5229": ("Lara", "phone"),
"LaraD": ("Lara", "computer"),
"KristiansiPhone": ("Martin", "phone"),
"Martins-MBP": ("Martin", "computer"),
}
nmap = subprocess.Popen(["sudo", "nmap", "-sP", ADDRESS], stdout=subprocess.PIPE)
for line in nmap.stdout:
for user, name in USERS.items():
if user in line:
print "%s is home(%s)" % name
nmap.wait()
唯一的第1点和第4点必须填满。
答案 1 :(得分:1)
我怀疑您的问题是sudo
命令行的nmap
部分。如果您将subprocess.call
替换为subprocess.check_call
,我认为您会发现该命令会引发CalledProcessError
。
据推测,您的用户帐户位于/etc/sudoers
文件中,但Web服务器不在。
由于shell的输出重定向运算符(>
)所做的第一件事是截断输出文件,因此尝试运行nmap
失败会导致零字节whohome.txt
。然后,Python脚本的其余部分对website.txt
执行相同操作,最终您的网站上无法显示任何内容。
sudo
。在我的Linux桌面上,我不需要以root身份运行nmap
才能执行本地ping扫描。如果您的系统上的情况属实,那么您应该可以删除sudo
命令的nmap
部分,并完成它。
但 是一个区别。当nmap
运行-pS
ping扫描时,root
会对每个目标执行更全面的测试。从旧的nmap
手册页(重点添加):
-sP
(跳过端口扫描)。[...]
-sP
选项默认发送ICMP回送请求,TCP SYN到端口443,TCP ACK到端口80,以及ICMP时间戳请求。 由非特权用户执行时,只有SYN数据包(使用连接呼叫)发送到目标上的端口80和443。 当特权用户尝试扫描本地以太网网络上的目标时,除非指定--send-ip
,否则将使用ARP请求。 [...]
sudo
。如果您需要这些额外信息(听起来就像这样),您需要以超级用户权限运行nmap
(或调用它的Python脚本)。我从未试图强制Web服务器执行此操作,但我认为您至少必须将Web服务器的用户添加到/etc/sudoers
。类似的东西:
apache localhost=/usr/bin/nmap -sP
或:
httpd ALL=/usr/local/bin/nmap
...依此类推,具体取决于用户名,nmap
所在的位置,您希望将参数限制为nmap
的严格程度等等。
nmap
。或者(我讨厌自己推荐这个 - 必须是一种更好的方法)是编写一个只执行的小型SUID(设置用户ID)程序你想要的nmap
命令。这是一个可以做到的C程序:
#include <stdio.h>
#include <unistd.h>
int main(void);
int main(void) {
int retval = 0;
char* const error_string = "ERROR: Failed to execute \"/usr/bin/map\"";
char* const nmap_args[] = {
"/usr/bin/nmap",
"-sP",
"192.168.1.0/24",
NULL
};
retval = execv("/usr/bin/nmap", nmap_args);
/* execv returns _only_ if it fails, so if we've reached this
* point, print an error and exit.
*/
perror(error_string);
return retval;
}
将上述内容保存为类似nmap_lan.c
的内容,并使用以下内容进行编译:
$ gcc -Wall -o nmap_lan nmap_lan.c
然后,将其移至您保留网站脚本的任何位置,并将作为root 移动,更改其所有权和权限:
# chown root:root nmap_lan # Or whatever group name you use.
# chmod 4555 nmap_lan
前导4
设置SUID位。目录的颜色ls
可能会显示该文件突出显示。权限应如下所示:
# ls -l nmap_lan
-r-sr-xr-x. 1 root root 6682 May 23 03:04 nmap_lan
任何运行nmap_lan
的用户都将被暂时提升为拥有nmap_lan
文件的用户(在本例中为root
),直到程序退出为止。这是非常慷慨的,这就是为什么我在该程序中硬编码所有的原因......为了改变它所做的任何事情 - 即使只是扫描的IP范围 - 你将不得不编辑{ {1}}文件,重新编译和重新安装。
我在我的命令行上测试了nmap_lan.c
,当由非特权用户运行时,它会产生特权用户nmap_lan
输出,而这些用户通常只能获得有限的输出。
一般来说,Python在解析shell参数方面非常比shell更好(因为nmap
的默认值是shell
),所以你的Python脚本尽可能多地完成工作,包括解析shell命令,重定向输入和重定向输出。
在Python中完成工作的一个主要优点是无法打开,读取,写入或关闭任何文件将导致立即崩溃和堆栈跟踪 - 而不是您已经发生的无声失败处理。
我重写了False
命令以使用明确分隔的参数列表。您可以通过将打开的文件流传递给call
参数来处理输出重定向。您可以通过让Python打开输出文件并明确地写入它来消除最后一点shell重定向。
stdout
此外,除非您需要nmap_file='/home/pi/whohome.txt'
with open(nmap_file, 'wt', encoding='ascii') as fout:
subprocess.call(
['/usr/bin/nmap', '-sP', '192.168.1.0/24'], # Or just ['nmap_lan']
stdout=fout,
universal_newlines=True,
)
output_file='/var/www/html/website.txt'
with open(nmap_file, 'rt', encoding='ascii') as fin:
with open(output_file, 'wt', encoding='ascii') as fout:
for line in fin:
...
print('Output here', file=fout) # Add `file=...` to each print.
文件用于其他内容,否则可以使用check_output
将whohome.txt
命令的输出存储为字符串,然后拆分,从而完全消除它它分成几行。 (nmap
参数还处理将universal_newlines
对象转换为bytes
,至少在Python 3中。)
str
请注意,我使用lines = subprocess.check_output(
['/usr/bin/nmap', '-sP', '192.168.1.0/24'], # Or just ['nmap_lan']
universal_newlines=True
).split('\n')
output_file='/var/www/html/website.txt'
with open(output_file, 'wt', encoding='ascii') as fout:
for line in lines:
...
print('Output here', file=fout) # Add `file=...` to each print.
块来免费关闭文件。
(最后,那一系列with
命令急于被重写为if
循环,你正在搜索的字符串作为该字典中的键,以及你想要的输出打印为值。)