elentz Posted December 20, 2016 Share Posted December 20, 2016 I just for some reason cannot wrap my head around this. I have this PHP code $output = shell_exec("sudo arp-scan --interface=eth0 --localnet --retry 1 --timeout 50 --numeric --plain --quiet | grep -e 80:82:87"); print_r ($output) Running this I get this on the page: 10.1.10.76 80:82:87:03:9d:38 10.1.10.84 80:82:87:03:d8:58 10.1.10.235 80:82:87:03:19:f0 This shows three devices on my network. IP address and a MAC address. I need to take that information and insert it into a db table. Can someone help me with how to accomplish this? Thanks Quote Link to comment Share on other sites More sharing options...
Psycho Posted December 20, 2016 Share Posted December 20, 2016 That is not what print_r() would output. Do you actually have an array? If so, we need to see the structure. Or, are you getting a string (which is what it looks like by what you posted)? Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 20, 2016 Share Posted December 20, 2016 For what it's worth, shell_exec() returns the output as a string. More information can be found here: http://php.net/manual/en/function.shell-exec.php Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 20, 2016 Share Posted December 20, 2016 Searching Google, the solution seems to come down to using explode() or preg_split() to break the string based on the white-space character. https://www.google.com/search?q=php%20get%20an%20array%20from%20shell_exec Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 20, 2016 Share Posted December 20, 2016 Most importantly you need to NOT store an array in your DB. Normalize your data (look it up) and create a table structure that holds the information properly. Quote Link to comment Share on other sites More sharing options...
elentz Posted December 20, 2016 Author Share Posted December 20, 2016 Thanks guys for the replies. The print_r is as far as I got. I needed a way to show that I was getting a result I could live with before trying to get it into a DB. I will check out the links you guys have offered. Thanks Quote Link to comment Share on other sites More sharing options...
Psycho Posted December 20, 2016 Share Posted December 20, 2016 (edited) Based on your first response you are getting a string with 6 pieces of data separates by spaces. There are three pairs of data (IP and MAC). Step 1: Split the data into an array of six elements $deviceData = explode(' ', $output); Step 2: Convert the array into separate elements for each device by 'chunking' it $devices = array_chunk($deviceData, 2); You should now have a multi-dimensional array with each sub-array representing a single device. Each sub-array would have two elements, the IP and the MAC address. Step 3: Now you can loop over those elements and validate that the pieces of data are valid and insert/update into your DB foreach($devices as $device) { $deviceIP = $device[0]; $deviceMAC = $device[1]; //Validate the values and then (if valid) insert/update into DB } Edited December 20, 2016 by Psycho Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 Thanks Psycho for your help. I think I uderstand what you have given me. It doesn't quite work yet. I get this error so far: Notice: Undefined offset: 1 in /var/www/html/cqadmin/macfind.php on line 11 When I set a print_r $devices I get this. To me it looks like the chunking isn't figuring out how to split the $output. Array ( [0] => Array ( [0] => 10.1.10.76 80:82:87:03:9d:38 10.1.10.84 80:82:87:03:d8:58 10.1.10.235 80:82:87:03:19:f0 ) ) Here is the code I used for the results I got <?php error_reporting(E_ALL); ini_set('display_errors', '1'); $output = shell_exec("sudo arp-scan --interface=eth0 --localnet --retry 1 --timeout 50 --numeric --plain --quiet | grep -e 80:82:87"); $deviceData = explode(' ', $output); $devices = array_chunk($deviceData,1); Print_r ($devices); foreach($devices as $device) { $deviceIP = $device[0]; $deviceMAC = $device[1]; //Validate the values and then (if valid) insert/update into DB } ?> Thanks Quote Link to comment Share on other sites More sharing options...
Psycho Posted December 22, 2016 Share Posted December 22, 2016 NO, the explode is not exploding as expected. It must be using something other than a space to separate the values. You will need to inspect the actual characters to know what to explode the data with. It might be a tab character ("\t") or some other white-space character. Output the variable $output to the page and then inspect the HTML to see if you can ascertain the actual character used as the delimiter. Post the actual HTML source here. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 22, 2016 Share Posted December 22, 2016 The arp-scan on my machine uses newlines to separate the hosts and tabs to separate the IP address from the MAC address: <IP> <MAC> <IP> <MAC> ... Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 22, 2016 Share Posted December 22, 2016 (edited) Have you tried preg_split() and the white-space character (\s) for the pattern? Here is an example found through the Google link provided earlier: $oparray = preg_split('/\s+/', trim($output)); Edited December 22, 2016 by cyberRobot Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 When I do a chrome inspect on the page it appears just as Jacques1 has indicated, no commas, ", ' just spaces between the IP and the MAC. I am going to try preg_split and see what happens Quote Link to comment Share on other sites More sharing options...
Solution Jacques1 Posted December 22, 2016 Solution Share Posted December 22, 2016 (edited) You don't need no regular expressions. Just look at the output of the command in the console and then split the string at the right characters. Surely you can recognize a newline and a tab. In my case, that's foreach (explode("\n", $arpOutput) as $host) { list($ip, $mac) = explode("\t", $host); echo "IP address: $ip, MAC address: $mac<br>"; } Edited December 22, 2016 by Jacques1 Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 Getting closer ! Using : $deviceData = preg_split('/\s+/', trim($output)); Instead of explode I am getting : Array ( [0] => 10.1.10.76 [1] => 80:82:87:03:9d:38 [2] => 10.1.10.84 [3] => 80:82:87:03:d8:58 [4] => 10.1.10.235 [5] => 80:82:87:03:19:f0 ) when I use print_r ($devices); Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 Jacques1 That gets me pretty much what I want! Fussing with it a little I can get just the MAC address and now all I have to do is get it into my DB table. Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 I am getting an error of: Undefined Offset: 1 on this line list($ip, $mac) = explode("\t", $host); Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 22, 2016 Share Posted December 22, 2016 Using : $deviceData = preg_split('/\s+/', trim($output)); Instead of explode Just to clarify, that was to replace step 1 of Psycho's solution. You should be able to use array_chunk() next, etc. https://forums.phpfreaks.com/topic/302791-i-have-an-array-that-i-need-to-get-into-a-db/?do=findComment&comment=1540606 You don't need no regular expressions. Just look at the output of the command in the console and then split the string at the right characters. Surely you can recognize a newline and a tab. Would there ever be a case where it uses "\r\n" instead of just "\n"? I honestly don't know. Quote Link to comment Share on other sites More sharing options...
elentz Posted December 22, 2016 Author Share Posted December 22, 2016 Success The Notice I had was caused by this line: list($ip, $mac) = explode("\t", $host); Through some experimentation and googling I came up with this: list($ip, $mac) = array_pad(explode("\t", $host),2,null); The notice is a thing of the past. I now get both the IP and the MAC addresses of the devices in the network. Now to get it into the DB Thank you everyone for all your help! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.