Rather new to coding, looking for a little help with having a variable output to a local html file. Both script and html are on the same machine. Script pulls signal level from a modem and I would like to have that displayed to a local html loading screen.
Signal Script:
#!/bin/bash
MODEM=/dev/ttyUSB3
MODEMCMD=AT+CSQ
{
echo -ne "$MODEMCMD"'\r\n' > "$MODEM"
if [ $? -eq 1 ]
then
echo "error";
exit;
fi
{
while read -t 1
do
if [[ $REPLY == +CSQ* ]]
then
arr1=$(echo "$REPLY" | cut -d' ' -f2)
arr2=$(echo "$arr1" | cut -d',' -f1)
echo "$arr2"
exit;
fi
done
echo "error";
} <"$MODEM"
} 2>/dev/null
Would like the output of this to display in a table on my html. Thanks!
When you host your own web server, the CGI protocol allows you to do server-side programming in any language you like; including Bash.
Here's a simple example that serves a web page that displays the current date and time, and refreshes every 10 seconds. Put the Bash script below in a file named test.cgi in the cgi-bin folder (on Linux/Apache: /usr/lib/cgi-bin) and make it executable (chmod +x test.cgi). The page's URL is: http://MyWebServer/cgi-bin/test.cgi
#!/bin/bash
cat << EOT
content-type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta http-equiv="refresh" content="10" />
</head>
<body>
$(date)
</body>
</html>
EOT
Please note: the empty line below content-type is relevant in the CGI protocol.
Replace date by your own Bash script; make sure it outputs something that resembles valid HTML. This means you need to take some effort to add HTML tags for your markup, and HTML-encode some characters (< > &) in your content.
Related
Notice:
While writing this question, I notice that there is a Github API that solves my problem without HTML parsing: https://api.github.com/repos/mozilla/geckodriver/releases/latest I decided to ask it anyway since I'm intested how to solve the described problem of parsing malformed HTML itself. So please dont downvote because there is a github API for it! We can replace github by any other page throwing validation errors.
I want to download the latest version of geckodriver. By fetching the redirection target of the latest tag, I'm on the releases page
curl $(curl -s "https://github.com/mozilla/geckodriver/releases/latest" --head | grep -i location | awk '{print $2}' | sed 's/\r//g') > /tmp/geckodriver.html
The first assets with geckodriver-vx.xxx-linux64.tar.gz is the required link. Since XML is schemantic, it should be parsed properly. Different tools like xmllint could parse it using xpaths. Since xpath is new for me, I tried a simple query on the header. But xmllint throws a lot of errors:
$ xmllint --xpath '//div[#class=Header]' /tmp/geckodriver.html
/tmp/geckodriver.html:51: parser error : Specification mandate value for attribute data-pjax-transient
<meta name="selected-link" value="repo_releases" data-pjax-transient>
^
/tmp/geckodriver.html:107: parser error : Opening and ending tag mismatch: link line 105 and head
</head>
^
/tmp/geckodriver.html:145: parser error : Entity 'nbsp' not defined
Sign up
^
/tmp/geckodriver.html:172: parser error : Entity 'rarr' not defined
es <span class="Bump-link-symbol float-right text-normal text-gray-light">→
...
There are a lot more. It seems that the github page is not properly well formed, as the specification requires it. I also tried xmlstarlet
xmlstarlet sel -t -v -m '//div[#class=Header]' /tmp/geckodriver.html
but the result is similar.
Is it not possible to extract some data using those tools when the HTML is not well formed?
curl $(curl -s "https://github.com/mozilla/geckodriver/releases/latest" --head | grep -i location | awk '{print $2}' | sed 's/\r//g') > /tmp/geckodriver.html
It may be simpler to use -L, and have curl follow the redirection:
curl -L https://github.com/mozilla/geckodriver/releases/latest
Then, xmllint accepts an --html argument, to use an HTML parser:
xmllint --html --xpath '//div[#class=Header]'
However, this doesn't match anything on that page, so perhaps you want to base your XPath on something like:
'string((//a[span[contains(.,"linux")]])[1]/#href)'
Which yields:
/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux32.tar.gz
I would like to make use of the
HTML::Template
module but somehow I can't set it up to work properly. Here is a very simple representative code I'm testing on:
use strict;
use warnings;
use CGI;
use HTML::Template;
my $test = new CGI;
my $tmpl = HTML::Template->new(filename => 'TemplateSimple.html');
$tmpl->param(
title => 'Test',
body => '<p>This is a test</p>',
);
my $out = $test->header(
-type => 'text/html',
-charset => 'utf-8'
);
print $out;
print $tmpl->output;
When calling the page I always end up with the browser displaying the server error message:
502 - Web server received an invalid response while acting as a
gateway or proxy server.
TemplateSimple.html
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title><TMPL_VAR NAME=title></title>
<link rel="SHORTCUT" ICON href="favicon.ico" />
</head>
<body>
<TMPL_VAR NAME=body>
</body>
</html>
I have to use CGI, because I want to process user input on the web page, but I would like to define the basic HTML structure in a template where I can insert code segments as necessary.
Edit
I think that it could have something to do with different configs between the local Perl (run from eclipse, which does run fine) and the Perl CGI config. Does anybody know of such a case?
Edit
After setting up a Perl CGI configuration in Eclipse, the script runs as expected from the local host. However, the problem when calling the page from an external source persists. So like DaveCross suggested, the bug lies in the web server configuration rather than the Perl script.
When initializing the HTML::Template object in the Perl script
my $tmpl = HTML::Template->new(filename => 'TemplateSimple.html');
I had to specify the full path instead of just the filename, so
my $tmpl = HTML::Template->new(filename => 'C:/inetpub/wwwroot/Project/TemplateSimple.html');
This solved my problem.
To whom it may interest, the webservice was set up with IIS 7, in the very basic and standard way.
I am currently running a Centos 7 instance. Already installed: postfix, dovecot, altermime. Sending and receiving emails works fine. However, what I am trying to do is attach a disclaimer for every mail sent.
My problem is in the disclaimer config there is a disclaimer text option, and a disclaimer html. But my email is always sent as plain text, so I receive emails with a disclaimer showing html tags.
How can i configure postfix or altermime to send html emails, or send a plain text with an image attached?
Here's my disclaimer config:
from_address=`grep -m 1 "From:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1`
if [ `grep -wi ^${from_address}$ ${DISCLAIMER_ADDRESSES}` ]; then
/usr/bin/altermime --input=in.$$ \
--disclaimer-html=/etc/postfix/disclaimer.html \
--disclaimer=/etc/postfix/disclaimer.txt \
--force-for-bad-html \
--xheader="X-Copyrighted-Material: Please visit http://www.company.com/privacy.h$
{ echo Message content rejected; exit $EX_UNAVAILABLE; }
fi
I've tried adding the html text in disclaimer.txt, or in disclaimer.html. The email is always received as plain text showing the html tags.
Any help would be gladly appreciated.
I have a expect script which does the following:
Spawns a.sh -> a.sh waits for user input
Spawns b.sh -> runs and finishes
I now want to send input to a.sh but having difficulties getting this working.
Below is my expect script
#!/usr/bin/expect
spawn "./a.sh"
set a $spawn_id
expect "enter"
spawn "./b.sh"
expect eof
send -i $a "test\r"
a.sh is
read -p "enter " group
echo $group
echo $group to file > file.txt
and b.sh is
echo i am b
sleep 5
echo xx
Basically, expect will work with two feasible commands such as send and expect. In this case, if send is used, then it is mandatory to have expect (in most of the cases) afterwards. (while the vice-versa is not required to be mandatory)
This is because without that we will be missing out what is happening in the spawned process as expect will assume that you simply need to send one string value and not expecting anything else from the session.
After the following code
send "ian\n"
we have to make the expect to wait for something afterwards. You have used expect eof for the spawned process a.sh . In a same way, it can be added for the b.sh spawned process as well.
"Well, then why interact worked ?". I heard you.
They both work in the same manner except that interact will expect some input from the user as an interactive session. It obviously expect from you. But, your current shell script is not designed to get input and it will eventually quit since there is no much further code in the script and which is why you are seeing the proper output. Or, even having an expect code alone (even without eof) can do the trick.
Have a look at the expect's man page to know more.
I've just got this working using
spawn "./a.sh"
set a $spawn_id
expect "enter"
spawn "./b.sh"
expect eof
set spawn_id $a
send "ian\n"
interact
My question now is why do you need interact at the end?
I have a ruby file namely sample.rb. I want to execute that from my form and, actually my ruby code when executed will write to a html file. So what i need to do is when i click on the button in the form it should execute the ruby code and then it has to open the html file that comes from execution in one of the frame in my form. Is it is possible? If possible! how to do?
What i have tried is
<?php
exec("./sample.rb")
?>
But what it does is. It simply took the url of the api that i have used in ruby code and it returns the json from that api.
May be you should use rails for that http://rubyonrails.org
You are invoking sample.rb as an external command, just like any other shell script. Therefore you have to capture and process its output yourself.
You say that "it returns the JSON from the api". That's fine, you can extract the data you are interested in, e.g.:
<?php
$json = exec("./sample.rb");
$data = json_decode($json);
$url = $data->url; # assuming there is an URL field
?>
Now you can for example output a link:
click
or generate some JavaScript:
<script>
window.location.href="<?php echo $url ?>";
</script>
or redirect the user via a HTTP header:
<?php
header("Location: $url");
?>