I have a need to scan for SSID's and display the results in a php page running in a localhost environment. I can get this script to run and return a value:
$command= "/sbin/iwlist wlan0 scan | grep 'ESSID' ";
$localSSID = exec ($command);
echo $localSSID;
the problem is that it only return the value of the last cell/SSID. for example when I scan in the terminal I get
ESSID:"SSID name X"
ESSID:"SSID name Y"
ESSID:"SSID name Z"
only the last one shows up.
Ideally what I need is just the name of each one to show in a select box as options for users to select.
Anyone have some mad grep regex skills that can offer up any suggestion? I would be very appreciative.
-GWC
See the documentation. Exec only returns the last line. Use the output parameter.
$output = array();
exec($command, $output);
Now, $output contains a string for every line of output.
Related
I'm setting up a script which takes some user data with the read command. Using this data I need to search the file range and then do some filtering.
Here's how it is,
Enter fromtime
read fromtime
Enter totime
read totime
Enter the ID
read id
Initially I SSH into a server and then there I have a directory, Records with path cd home/report/records here, I have:
REC_201901020345.gz (yyyymmddhhmm)
REC_201901120405.gz
REC_201903142543.gz
and so on.
These files have data along with the $id.
When the user inputs $fromtime and $totime it will be of format yyyymmddhh . Here, I need to go to that range of files and then grep for the $id and display. For example:
If $fromtime is 2019010103 and $totime is 2019031425. I need to go to only those specific range of files that is REC_201901020345.gz, REC_201901120405.gz, REC_201903142543.gz and perform the grep to find the id entered by the user.
I have tried this using an if condition but it doesn't seem to work. I am new to writing scripts like these. There might be mistakes when I have described everything here. Sorry for the same.
source config.sh
Enter fromtime
read fromtime
Enter totime
read totime
Enter the ID
read id
ssh $user#$ip
cd /home/report/records
# <-- need to know what to add here as described here, to navigate to the
# <-- specific range $fromtime-$totime. Then the command to find id will be
zfgrep $id *.gz
The result should be only the the data with the id's in the specified range of .gz files.
Try below command.
echo -e "$(ls -1 REC_????????????.gz 2>/dev/null)\nREC_${fromtime}##\nREC_${totime}##" | sort | sed -n "/##/,/##/p" | sed '1d;$d' | xargs zfgrep -a "$id"
Explanation:
'fromdate' and 'todate' along with a ## (say marker) is appended to the output of ls.
Sorted the input, resulting in desired file names enclosed with marker.
Both sed, prints only lines between marker.
Last one is the command, supposed to be executed for each file name.
You can omit pipes and all next commands, starting from end, and see how output is building.
To get the list of files within the given range (fromtime, totime), the following shell script may be used:
declare -i ta
for file in REC*.gz
do
ta=$(echo "${file}" | grep -oP 'REC_\K(.*)(?=[[:digit:]]{2}.gz)')
if [ "${ta}" ] ; then
if [ ${ta} -le ${totime} -a ${ta} -ge ${fromtime} ] ; then
echo -e "${file}"
fi
fi
done
I'm trying to return the content of a folder in a Linux enviroment.
To do this I run the code below:
//this line returns folders and files from current folder
$reg = shell_exec ("ls -A");
//in this line I just try to show the info with the desired structure.
$reg = "stat --printf='%n|%s|%s|%F|%y|%a' ".$reg." | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B";
//This prints the content of $reg
echo $reg;
//I manually input the string returned by $reg and I receive the correct output
echo shell_exec ("stat --printf='%n|%s|%s|%F|%y|%a' .file1 file2 | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B");
//This just prints the result of "stat --printf='%n|%s|%s|%F|%y|%a' .file1"
echo shell_exec ($reg);
The problem is that the two last "echo" instructions return different outputs given (in theory) identical inputs.
How can I solve this?
When ls detects that it's being piped into another command it writes one file per line, screwing up your command.
You could either replace them with spaces
$reg= str_replace("\n", " ", shell_exec("ls -A"));
or use ls as a substitution
$reg = "stat --printf='%n|%s|%s|%F|%y|%a' $(ls -A) | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B";
I'm running PHP on a Windows Server and I have a script that uses PowerShell to perform some WMI queries. I'm taking the results of the query and exploding it by line break so that each property of the WMI class is its own line (and later will be used for other stuff).
The problem I'm having is that by default, the command prompt window width is limited to 80 characters so when the PHP script obtains the results of the WMI query, certain lines that exceed 80 characters are broken up into numerous lines and I'd really like each line to only be one line regardless of how long the string is.
I've tried logging into the server and changing the default width of the command prompt as well as both 32- and 64-bit PowerShell windows. When I run the commands directly in those applications, I can see it's no longer breaking on 80 characters. However, my PHP script still does.
Here's a snippet of my code:
exec("powershell.exe -Command \" & { Get-WmiObject -Query 'Select * From Win32OperatingSystem' | Format-List *} \" ", $Output, $ReturnValue);
foreach ($Output as $PSOutput) {
$ExplodePSOutput = explode("\r\n", $PSOutput);
foreach ($ExplodePSOutput as $WMIProperty) {
echo $WMIProperty."<br>";
}
}
Here's an example of what the output is like:
Status : OK
Name : Microsoft Windows 10 Enterprise|C:\
WINDOWS|\Device\Harddisk0\Partition
2
FreePhysicalMemory : 9224968
But I'm wanting it to look like this:
Status : OK
Name : Microsoft Windows 10 Enterprise|C:\WINDOWS|\Device\Harddisk0\Partition2
FreePhysicalMemory : 9224968
Update:
My ultimate goal was to extract each property name from the selected WMI class. Since each property named was followed with " : ", I was able to work around this problem by searching each exploded string for this pattern and returning the value to the left of that. If that pattern doesn't exist, it's presumably a line that was broken because it went over the 80 character limit.
$PatternPosition = strpos($WMIPropertyResult, " : ");
$WMIPropertyName = substr($WMIPropertyResult, 0, $PatternPosition);
PowerShell formats the output to align all of the property values but it formats it based on the longest property name and property names will obviously change based on what WMI class is being queried. So it makes more sense to search for the " : " pattern instead of hardcoding a value in the substr() function.
I'll leave this post around in case anyone has a suggestion on the original question but for my use case, I believe I have a sufficient workaround.
I am total noob in scripting, and try to find out where is the problem in my code. I have a text files with customer details, first line of the file is username, second is real name. This details i need to pass to php. First, I need to find oldest file in directory. I created bash script which returns customer username:
oldest=`ls -tr1 temp/data/*.details|head -1`
head -n1 $oldest
This finds odest file (temp/data/xxx.details) and returns username, let's say xxx.
Now, to the php:
$username = shell_exec('./oldest_order.sh');
$name = shell_exec('head -2 temp/data/'.$username.'.details | sed -n 2p');
I can get username in my php, with the first line: it's xxx, but second line does not work, However, if I change '.$username.' to xxx, it works, so problem is somewhere around this variable.
Please advice.
Perhaps there is a new-line or space at the end or the beginning.
You can check that by doing a var_dump($username);. That will give you the actual length of the string so that you can compare it with the length you think it should have.
If it is white-space at the beginning or the end, you can use:
$name = shell_exec('head -2 temp/data/'.trim($username).'.details | sed -n 2p');
I have a list of full file paths. All of the full file paths look like "/dir1/dir2/dir3/s..". I want to completely remove the s. from the filename. There is the possibility of a filename being plural, for example s.asdfs.cpp. I do not want to remove the second occurence of s. since that is part of the actual filename and not a reoccuring theme in every full file path in the list.
Running the following in shell works as I want it to:
echo /dir1/dir2/dir3/s.filenames.cpp | sed 's#\(.*\)\/s\.\([^\/]*\)#\1\/\2#g'
Gives the desired result of:
/dir1/dir2/dir3/filenames.cpp
But if I run the following in php:
$formatted_filename = exec("echo ".$filename." | sed 's#\(.*\)\/s\.\([^\/]*\)#\1\/\2#g'");
where
$filename = /dir1/dir2/dir3/s.filenames.cpp;
And then in my bash shell run
php -q script_name_that_contains_command_above.php > test.html
and refresh my firefox browser that displays test.html I get very strange results. In place of where this edited file path should be listed I get
<strange box>/<strange box>
where
<strange box>
is a small box with 2 rows and 2 columns consisting of 0's except for the bottom right cell. The first occurence has a 1 in the bottom right cell, and the second occurence has a 2 in the bottom right cell.
The sed command works, but php, or the exec command is interpreting it incorrectly I believe. Any ideas?
The solution for using exec with this particular regular expression was to use the php function, preg_replace()
preg_replace("/\/s/./", "/", $filename);