Variable inside shell_exec - php

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

Related

Shell script to grep in a range of files

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

how to shell script write multi line text to file read from mysql?

I am facing a problem while writing a shell script. i have table in a database where there is a text field.. i need to write that field into a file.
database fields are id, file_name, text
here is my script
#!/bin/bash
while read -a row
do
cat <<EOF >/root/${row[1]}
${row[2]}
EOF
sleep 1
done < <(echo "SELECT * FROM installation WHERE status = 1" | mysql -h 127.0.0.1 -u root -padmin -D data -s)
I have tried with
echo "${row[2]}" > /root/${row[1]}
But its writing the 1st line only, but the
text field is multiline text and i need write full text in that file
please help
By default read -r row will do word splitting by space/tab/new-line. Because the text field from table contains new-lines, word splitting would cut your text result. In this situation it's hard to avoid it.
I recommend you should replace the new-line to another mark, e.g. ### or just new-line, using REPLACE(text, "\n", 'new-line')(I am not familiar with sql REPlACE function) in SQL, then get result from shell, then use ${row[2]//new-line/$'\n'} to convert the new-line back.

Extract ZIP's contents on screen but avoid extra information except of the file names

I am looking for a command that will print all the contents of an archive (including sub-folders and it's files) without extracting the actual archive on the disk, but only on screen.
I achieve something using some other questions and answers from this site, and here is my command:
unzip -l test.zip | awk '/-----/ {p = ++p % 2; next} p {print $NF}'
The output:
0 04-11-2009 13:43 jodconverter-webapp-2.2.2/ 1815 04-11-2009 13:43 jodconverter-webapp-2.2.2/README.txt 0 04-11-2009 13:43 jodconverter-webapp-2.2.2/src/ 5349 04-11-2009 13:42 jodconverter-webapp-2.2.2/src/jodconverter-webapp-2.2.2-sources.jar 26436 04-11-2009 13:43 jodconverter-webapp-2.2.2/LICENSE.txt 3819 04-11-2009 13:43 jodconverter-webapp-2.2.2/ChangeLog.txt 3314202 04-11-2009 13:42 jodconverter-webapp-2.2.2/jodconverter-webapp-2.2.2.war
As you can see the output is one line, and includes some extra information that I don't really need.
I want an output of this kind:
jodconverter-webapp-2.2.2/
jodconverter-webapp-2.2.2/README.txt
jodconverter-webapp-2.2.2/src/
jodconverter-webapp-2.2.2/src/jodconverter-webapp-2.2.2-sources.jar
.
.
.
So not only I want to output the file names only (and their full path) and avoid any extra other information like time permissions and so on, but also I want to use something like break-line to distinguish different files.
Keep in mind that this command will run on a PHP file to get the contents of the file, so I don't know if this can help us to use the <br> to do the break lines.
Is that possible with a single command?
Well, I can't think a command that will return you back the output you need, but may someone else can know something more.
What I would do in your case is to split the line into array and play with it until you get what you want.
You actually have to find a pattern that will work for all cases.
With a brief look on the command's output I came with the following decisions:
You splitting the line using as separator the space (i.e explode() )
The pattern I can see is that there exist a time of the form xx:xx exactly before the actual file/directory ! So you can check if the current line is a valid 24-based time using a regular expression then that means if that is the case and you are in the $i position of the array the $i+1 is what you are looking for, and therefore you can copy that to a new array.
Repeat
I think that is a bit pain, but at least is a solution.

Getting WiFi SSID to display in php (need GREP help)

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.

PHP Exec() Using Sed Gives Strange Results

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

Categories