shell script output in html + email that html - html

Using Solaris
I have a monitoring script that uses other scripts as plugins.
Theses pugins are also scripts which work in difffernt ways like:
1. Sending an alert while high memory uilization
2. High Cpu usage
3. Full disk Space
4. chekcking the core file dump
Now all this is dispalyed on my terminal and I want to put them in a HTML file/format and send it as a body of the mail not as attachment.
Thanks .

You can use an ANSI to HTML convertor like so:
top -b -n 1 | /tmp/ansi2html.sh | mail -s "Server load" -a "Content-Type: text/html" myboss#example.com
Works even with colours. See Coloured Git diff to HTML.

Related

How to convert modern HTML to PDF

In 2016, the best way to convert HTML files to PDF from the command line was using wkhtmltopdf. Unfortunately, it seems that that is not really maintained anymore. It doesn't support a lot of things like flexbox.
One can use headless chrome/chromium to do it:
chrome --headless --print-to-pdf="path/to/pdf" https://your_url
but that has no options such as margins, paper type, control over header/footer, screen size, etc.
It appears that there is no plan to add those into headless chrome as command line options (one needs to use the dev tools interface):
https://bugs.chromium.org/p/chromium/issues/detail?id=603559#c89
How can one convert HTML files to PDF from the command line that gives control over how the document prints (margins, etc., from above), and supports modern html/css? Of course, once one can convert from the command line, you can also convert using a programming language of your choice.
Here is a command line tool that you can use to convert HTML pages to PDF just as they would be in chrome. Once you have it installed, you can use it with whatever programming language you want (Python, Java, PHP, etc.) to automatically generate PDFs from HTML web pages or documents. All of the dependencies should be well maintained well into the future, so it shouldn't have the same issues as things like wkhtmltopdf that were difficult to maintain.
URLs:
https://www.npmjs.com/package/chromehtml2pdf
https://github.com/dataverity/chromehtml2pdf
To install it, you'll need npm, and type:
npm install chromehtml2pdf
or to make it globally available to all users on the system
npm install -g chromehtml2pdf
Command line usage:
chromehtml2pdf --out=file.pdf --landscape=1 https://www.npmjs.com/package/chromehtml2pdf
For help (to view all possible options), type:
chromehtml2pdf --help
Feel free to make pull requests on github.
If all you wanted to do was get rid of Chrome's default header/footer, and you control the page in question, you can do that with CSS, without having to use something more complex than a simple command line call.
#media print {
#page { margin: 0; }
}
Of course, you probably do want margins on your pages, so you'll need to fake those. The complexity of doing so varies depending on how many pages you meant to emit to PDF. The recommended body margins in the linked Answer will work if you're emitting a 1-pager. If not, you'll need to use other methods. For example, for multiple pages, you can add body padding on the left and right, then wrap each page's content in a tag with margin for top and bottom.
https://stackoverflow.com/a/15150779/176877
Project Gotenberg does this and a bit more. Including margin manipulation as well as WebHooks, timeouts, merging, and other formats.
To try it
docker run --rm -p 3000:3000 thecodingmachine/gotenberg:6
Example
curl --request POST \
--url http://localhost:3000/convert/url \
--header 'Content-Type: multipart/form-data' \
--form remoteURL=https://brave.com \
--form marginTop=0 \
--form marginBottom=0 \
--form marginLeft=0 \
--form marginRight=0 \
-o result.pdf
- HTML and Markdown conversions using Google Chrome headless

Is there something like a "CSS selector" or XPath grep?

I need to find all places in a bunch of HTML files, that lie in following structure (CSS):
div.a ul.b
or XPath:
//div[#class="a"]//div[#class="b"]
grep doesn't help me here. Is there a command-line tool that returns all files (and optionally all places therein), that match this criterium? I.e., that returns file names, if the file matches a certain HTML or XML structure.
Try this:
Install http://www.w3.org/Tools/HTML-XML-utils/.
Ubuntu: aptitude install html-xml-utils
MacOS: brew install html-xml-utils
Save a web page (call it filename.html).
Run: hxnormalize -l 240 -x filename.html | hxselect -s '\n' -c "label.black"
Where "label.black" is the CSS selector that uniquely identifies the name of the HTML element. Write a helper script named cssgrep:
#!/bin/bash
# Ignore errors, write the results to standard output.
hxnormalize -l 240 -x $1 2>/dev/null | hxselect -s '\n' -c "$2"
You can then run:
cssgrep filename.html "label.black"
This will generate the content for all HTML label elements of the class black.
The -l 240 argument is important to avoid parsing line-breaks in the output. For example if <label class="black">Text to \nextract</label> is the input, then -l 240 will reformat the HTML to <label class="black">Text to extract</label>, inserting newlines at column 240, which simplifies parsing. Extending out to 1024 or beyond is also possible.
See also:
https://superuser.com/a/529024/9067 - similar question
https://gist.github.com/Boldewyn/4473790 - wrapper script
I have built a command line tool with Node JS which does just this. You enter a CSS selector and it will search through all of the HTML files in the directory and tell you which files have matches for that selector.
You will need to install Element Finder, cd into the directory you want to search, and then run:
elfinder -s "div.a ul.b"
For more info please see http://keegan.st/2012/06/03/find-in-files-with-css-selectors/
There are two tools:
pup - Inspired by jq, pup aims to be a fast and flexible way of exploring HTML from the terminal.
htmlq - Likes jq, but for HTML. Uses CSS selectors to extract bits of content from HTML files.
Examples:
$ wget http://en.wikipedia.org/wiki/Robots_exclusion_standard -O robots.html
$ pup --color 'title' < robots.html
<title>
Robots exclusion standard - Wikipedia
</title>
$ htmlq --text 'title' < robots.html
Robots exclusion standard - Wikipedia
Per Nat's answer here:
How to parse XML in Bash?
Command-line tools that can be called from shell scripts include:
4xpath - command-line wrapper around Python's 4Suite package
XMLStarlet
xpath - command-line wrapper around Perl's XPath library

getting HTML source or rich text from the X clipboard

How can rich text or HTML source code be obtained from the X clipboard? For example, if you copy some text from a web browser and paste it into kompozer, it pastes as HTML, with links etc. preserved. However, xclip -o for the same selection just outputs plain text, reformatted in a way similar to that of elinks -dump. I'd like to pull the HTML out and into a text editor (specifically vim).
I asked the same question on superuser.com, because I was hoping there was a utility to do this, but I didn't get any informative responses. The X clipboard API is to me yet a mysterious beast; any tips on hacking something up to pull this information are most welcome. My language of choice these days is Python, but pretty much anything is okay.
To complement #rkhayrov's answer, there exists a command for that already: xclip. Or more exactly, there's a patch to xclip which was added to xclip later on in 2010, but hasn't been released yet that does that. So, assuming your OS like Debian ships with the subversion head of xclip (2019 edit: version 0.13 with those changes was eventually released in 2016 (and pulled into Debian in January 2019)):
To list the targets for the CLIPBOARD selection:
$ xclip -selection clipboard -o -t TARGETS
TIMESTAMP
TARGETS
MULTIPLE
SAVE_TARGETS
text/html
text/_moz_htmlcontext
text/_moz_htmlinfo
UTF8_STRING
COMPOUND_TEXT
TEXT
STRING
text/x-moz-url-priv
To select a particular target:
$ xclip -selection clipboard -o -t text/html
 rkhayrov
$ xclip -selection clipboard -o -t UTF8_STRING
rkhayrov
$ xclip -selection clipboard -o -t TIMESTAMP
684176350
And xclip can also set and own a selection (-i instead of -o).
In X11 you have to communicate with the selection owner, ask about supported formats, and then request data in the specific format. I think the easiest way to do this is using existing windowing toolkits. E,g. with Python and GTK:
#!/usr/bin/python
import glib, gtk
def test_clipboard():
clipboard = gtk.Clipboard()
targets = clipboard.wait_for_targets()
print "Targets available:", ", ".join(map(str, targets))
for target in targets:
print "Trying '%s'..." % str(target)
contents = clipboard.wait_for_contents(target)
if contents:
print contents.data
def main():
mainloop = glib.MainLoop()
def cb():
test_clipboard()
mainloop.quit()
glib.idle_add(cb)
mainloop.run()
if __name__ == "__main__":
main()
Output will look like this:
$ ./clipboard.py
Targets available: TIMESTAMP, TARGETS, MULTIPLE, text/html, text/_moz_htmlcontext, text/_moz_htmlinfo, UTF8_STRING, COMPOUND_TEXT, TEXT, STRING, text/x-moz-url-priv
...
Trying 'text/html'...
I asked the same question on superuser.com, because I was hoping there was a utility to do this, but I didn't get any informative responses.
Trying 'text/_moz_htmlcontext'...
<html><body class="question-page"><div class="container"><div id="content"><div id="mainbar"><div id="question"><table><tbody><tr><td class="postcell"><div><div class="post-text"><p></p></div></div></td></tr></tbody></table></div></div></div></div></body></html>
...
Trying 'STRING'...
I asked the same question on superuser.com, because I was hoping there was a utility to do this, but I didn't get any informative responses.
Trying 'text/x-moz-url-priv'...
http://stackoverflow.com/questions/3261379/getting-html-source-or-rich-text-from-the-x-clipboard
Extending the ideas from Stephane Chazelas, you can:
Copy from the formatted source.
Run this command to extract from the clipboard, convert to HTML, and then (with a pipe |) put that HTML back in the clipboard, again using the same xclip:
xclip -selection clipboard -o -t text/html | xclip -selection clipboard
Next, when you paste with Ctrl+v, it will paste the HTML source.
Going further, you can make it a shortcut, so that you don't have to open the terminal and run the exact command each time. ✨
To do that:
Open the settings for your OS (in my case it's Ubuntu)
Find the section for the Keyboard
Then find the section for shortcuts
Create a new shortcut
Set a Name, e.g.: Copy as HTML
Then as the command for the shortcut, put:
bash -c "xclip -selection clipboard -o -t text/html | xclip -selection clipboard"
Note: notice that it's the same command as above, but put inside of an inline Bash script. This is necessary to be able to use the | (pipe) to send the output from one command as input to the next.
Set the shortcut to whatever combination you want, preferably not overwriting another shortcut you use. In my case, I set it to: Ctrl+Shift+c
After this, you can copy some formatted text as normally with: Ctrl+c
And then, before pasting it, convert it to HTML with: Ctrl+Shift+c
Next, when you paste it with: Ctrl+v, it will paste the contents as HTML. 🧙✨

curl: downloading from dynamic url

I'm trying to download an html file with curl in bash. Like this site:
http://www.registrar.ucla.edu/schedule/detselect.aspx?termsel=10S&subareasel=PHYSICS&idxcrs=0001B+++
When I download it manually, it works fine. However, when i try and run my script through crontab, the output html file is very small and just says "Object moved to here." with a broken link. Does this have something to do with the sparse environment the crontab commands run it? I found this question:
php ssl curl : object moved error
but i'm using bash, not php. What are the equivalent command line options or variables to set to fix this problem in bash?
(I want to do this with curl, not wget)
Edit: well, sometimes downloading the file manually (via interactive shell) works, but sometimes it doesn't (I still get the "Object moved here" message). So it may not be a a specifically be a problem with cron's environment, but with curl itself.
the cron entry:
* * * * * ~/.class/test.sh >> ~/.class/test_out 2>&1
test.sh:
#! /bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/sbin
cd ~/.class
course="physics 1b"
url="http://www.registrar.ucla.edu/schedule/detselect.aspx?termsel=10S<URL>subareasel=PHYSICS<URL>idxcrs=0001B+++"
curl "$url" -sLo "$course".html --max-redirs 5
Edit: Problem solved. The issue was the stray tags in the url. It was because I was doing sed s,"<URL>",\""$url"\", template.txt > test.sh to generate the scripts and sed replaced all instances of & with the regular expression <URL>. After fixing the url, curl works fine.
You want the -L or --location option, which follows 300 series redirects. --maxredirs [n] will limit curl to n redirects.
Its curious that this works from an interactive shell. Are you fetching the same url? You could always try sourcing your environment scripts in your cron entry:
* * * * * . /home/you/.bashrc ; curl -L --maxredirs 5 ...
EDIT: the example url is somewhat different than the one in the script. $url in the script has an additional pair of <URL> tags. Replacing them with &, the conventional argument seperators for GET requests, works for me.
Without seeing your script it's hard to guess what exactly is going on, but it's likely that it's an environment problem as you surmise.
One thing that often helps is to specify the full path to executables and files in your script.
If you show your script and crontab entry, we can be of more help.

Is it possible to email the contents of vim using HTML

I like to view the current differences in the source files I'm working on with a command like:
vim <(svn diff -dub)
What I'd really like to be able to do is to email that colorized diff. I know vim can export HTML with the :TOhtml, but how do I pipeline this output into an html email? Ideally. i'd like to be able to send an html diff with a single shell script command.
The following one-liner produces an HTML file named email.html:
diff file1 file2 | vim - +TOhtml '+w email.html' '+qall!'
You can now use Pekka’s code to send the email.
However, I believe in using the right tool for the right job – and VIM may not be the right tool here. Other highlighters exist and their use is more appropriate here.
For example, Pygments can be harnessed to produce the same result, much more efficiently and hassle-free:
diff -u report.log .report.log | pygmentize -l diff -f html > email.html
Notice that this produces only the actual text body, not the style sheet, nor the surrounding HTML scaffold. This must be added separately but that’s not difficult either. Here’s a complete bash script to produce a valid minimal HTML file:
echo '<!DOCTYPE html><html><head><title>No title</title><style>' > email.html
pygmentize -S default -f html >> email.html
echo '</style></head><body>' >> email.html
diff -u report.log .report.log | pygmentize -l diff -f html >> email.html
echo '</body></html>' >> email.html
EDIT In case that Pekka’s code didn’t work – as for me – because you don’t have the required versions of mail and mutt installed then you can use sendmail as follows to send the HTML email:
( echo 'To: email-address#example.com'
echo 'Content-Type: text/html'
echo 'Subject: test'
echo ''
cat email.html ) | sendmail -t
It’s important to leave an empty line between the header and the body of the email. Also, notice that it’s of course unnecessary to create the temporary file email.html. Just paste the rest of the commands into the right place above and delete the redirects to file.
I'm no Linux Guru, but this looks like it should serve your needs to pipe your output into:
Send an HTML file as email from the command line. (uses mail)
There's also a one-line mutt example here:
mutt -e "my_hdr Content-Type: text/html"
-s "my subject" you#xxxxxxxxxxx < message.html
this will generate a pure HTML E-Mail with no pure text alternative - for that you would have to build multi-part mail... But maybe it'll do for what you need.