How can I add syntax highlighting to a make error message? - bash

Summary
I want to manually add syntax highlighting of specific words in error messages. I tried with a pipeline to awk, but this doesn't seem to work with the entire message that is thrown by make. Can anybody help me to get the following pipeline working for make's entire error message?
make | awk '{for(i=1;i<=NF;i++){ if($i~/error/ || $i~/Built/) $i=sprintf("\033[0;36m %s \033[0;00m",$i)}; print}'
Or maybe—better still—a different approach to my
Situation (in detail)
To build my latex project, I use Cmake together with UseLATEX (github page). That way, I can simply render my document by executing make from inside a build folder. Only problem: There is no syntax highlighting for the wall of text of an error message. I need to add a minimal version of this, to work productively. (Maybe words could be highlighted globally in my terminal?)
By passing the output in a pipeline to awk (manpage)—inspired by this askubuntu post—I was able to highlight make's success message, pdflatex myfile.tex's success and error message, but not make's error message, it did not highlight the interesting parts of the long message.
By highlighting Built in the code snippet above, one can see that it does highlight when the first command make succeeds.
The problem is that I do not fully understand when the pipeline passes what. It seems that some output can get highlighted and some cannot.
Thanks for any help!
Steps needed to reproduce
To get into exactly the situation at hand, you need a project folder containing
build/
cmake/
myfile.tex
CMakeLists.txt
with cmake/ containing UseLATEX.cmake
and CMakeLists.txt reading
include(cmake/UseLATEX.cmake)
ADD_LATEX_DOCUMENT(myfile.tex)
and myfile.tex being a valid or non-valid latex document, e.g.
\documentclass{article}
\begin{document}
Some \undefined command
\end{document}
From inside the build/ folder, call cmake .., and then make, or rather the full command above.

The message is written on stderr, not on stdout. You have to handle stderr. In bash, you can:
make 2> >(do_something_with_stderr >&2) | do_something_with_stdout
Because | changes buffering, it's not always wanted in interactive programs. For interactive I prefer:
make 2> >(do_something_with_stderr >&2) >(do_something_with_stdout)
and sometimes that's one function:
some_func() { do_something; }
make 2> >(some_func >&2) >(some_func)

Related

Building libssh project - target pattern contains no '%'

I'm trying to install libssh-0.8.5 onto Ubuntu 16.04 using the instructions from the install.readme provided. I follow every step as stated, but I get an error after executing the make command to build the project. The error is as follows:
[ 65%] Built target exec
tests/CMakeFiles/ssh_ping.dir/flags.make:8: *** target pattern contains no '%'. Stop.
CMakeFiles/Makefile2:1696: recipe for target 'tests/CMakeFiles/ssh_ping.dir/all' failed
make[1 ]: *** [tests/CMakeFiles/ssh_ping.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2
I have researched and seen that it could be a syntax error somewhere in my make file that is preventing the build to continue. I have looked at the target make file giving the problem, but cant seem to identify what is causing the error.
The flag.make file is as follows:
The problem seems to be coming from the highlighted bold line. Can anyone see what I am missing?
On StackOverflow (and most other similar sites), please cut and paste text into your questions and format them using the proper markdown facilities, rather than attaching images containing text. The latter is difficult to read and we can't cut and paste it into our answer to show where things are going wrong.
You cannot embed newlines in quoted strings, in makefiles. Make is completely line-oriented and does not parse quotes at all. So to make this:
FOO = "bar
biz"
is not considered one line assigning a value containing a newline to a variable FOO. Instead, it's considered two lines, the first of which is assigning the value "bar to variable FOO and the second of which is a syntax error since make can't parse the string baz" as a valid command.
Apparently ssh wasn't installed properly on your platform, while cmake relies on it. I am a bit surprised that cmake itself did not raise an error when generating flag.make but as I don't use cmake I do not know whether it is its normal behaviour or not.
Anyway, when cmake tried to detect your version of OpenSSH it did it by running ssh and got an error message instead of the version number it wanted. This error message got inserted in the generated flag.make Makefile. Because the second line of this error message (I could copy-paste it here if it was not in a picture in your question) has the:
a: b: c
form, make tried to interpret it as a static pattern rule but as it contains no % wildcard character, make raised a syntax error.
What happens if you try to run /usr/bin/ssh -V on the command line?

Python Sphinx Substitutions not throwing errors or warnings like ref's

In an effort to make the .rst files more readable I started using substitutions instead of refs everywhere for common objects. For example :ref:user-story is now |user story|. The output is fine, but when a user mistypes a substitution we do not see any errors when we execute make livehtml like we do when we use :refs:. Is there a way to see undefined references like we do with ref's.
I've tried, with no success.
make livehtml -W
make livehtml -Wv
I do see errors like duplicate substitutions, but not unresolved substitutions.
Sphinx 1.4.6
Windows 10
Python 2.7.11
After some trial and error using -n for nit-picky mode displayed undefined substitution errors when building.
make livehtml -n

using sylfilter with procmail

I have been using sylfilter for over a year now (it is available from http://sylpheed.sraoss.jp/sylfilter/) and it works great as a filtering tool (no complaints). However, I have been trying to use procmail with sylfilter, but have been having a lot of trouble.
The web page for the filter shows:
sylfilter ~/Mail/inbox/1234
as the example to classify a message.
The return values are as following:
0 junk (spam)
1 clean (non-spam)
2 uncertain
127 other errors
I have been trying to incorporate sylfilter with procmail but not with much success. The big issue as compared with some other spam tool like bogofilter is that sylfilter does not make any changes to the e-mail message itself
(unlike bogofilter, for which examples abound on the web, and which
puts in a X-Bogosity field in the message header). I want everything
that is classified as Junk to go to $HOME/Mail/Junk and everything that
is not to be further classified into folders such as procmail rules.
Perhaps the stuff that returns 2 can go to $HOME/Mail/uncertain.
Here is my latest attempt based on suggestions made in the Fedora mailing list.
:0 Wc
| /usr/bin/sylfilter /dev/stdin
:0 a
$HOME/Mail/Junk/.
However, this does not process the e-mail message using sylfilter (and
the logfile says "No input file." before going on to process the other
rules). So, I was wondering if anyone here knew of a similar case and knew the answer to this question.
I am not familiar with sylfilter, and the (somewhat vague) problem description makes me think there is something wrong with feeding it a message on standard input. But if you can make that work, the following is how you examine a program's exit code in Procmail.
:0
* ? sylfilter /dev/stdin
$HOME/Mail/Junk/.
# You should now have the exit code in $? if you want it for further processing
SYLSTATUS=$?
:0
* SYLSTATUS ?? ^^1^^
$HOME/Mail/INBOX/.
# ... etc
The condition succeeds if sylfilter returns a success (zero) exit code; if it fails, we fall through to subsequent recipes. We save $? to a named variable so that we can examine its value even if a subsequent recipe resets the system global $? by invoking some other external program.
By the by, you should not need to hard-code the path to sylfilter. If it's in a nonstandard location, amend the PATH at the beginning of your .procmailrc rather than littering your code with explicit paths to executables. So if it's in /usr/local/really/sf/sylfilter, you'd put
PATH=/usr/local/really/sf:$PATH
If you need the message in a temporary file, try something like this;
TMP=`mktemp -t sylf.XXXXXXXX`
TRAP='rm -f $TMP'
:0c
$TMP
:0
* ? sylfilter $TMP
$HOME/Mail/Junk/.
# etc as above
The mktemp command creates a unique temporary file. The TRAP assignment sets up a command sequence to run when Procmail terminates; this takes care of cleaning out the temporary file when we are done. Because we will be the only writer to this file, we don't care about locking while writing a copy of the message to this file.
For more nitty-gritty syntax details, see also http://www.iki.fi/era/procmail/quickref.html

Passing file into program with bash

I am trying to pass a file into a program for data processing with bash and I am wondering if I have the correct syntax
/home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt | /home/mumps/Medline2012/getDocs.mps > /home/mumps/CS3150/Scripts/HW1/textfiles/Titles.txt
The text files I am sending in are all valid and correctly formatted, but am just getting back a file error from the getDocs.mps (I should note that getDocs does work properly because it was something that my teacher passed out along with the debian vdi and other people aren't having a issue with it.)
getDocs does however call a text file that is located in Medline2012 as well which is where the error is coming from I believe.
Or just use bash redirection throughout without cat.
/home/mumps/Medline2012/getDocs.mps < /home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt > /home/mumps/CS3150/Scripts/HW1/textfiles/Titles.txt
/home/mumps/Medline2012/getDocs.mps < /home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt > /home/mumps/CS3150/Scripts/HW1/textfiles/Titles.txt
or
~/Medline2012/getDocs.mps < ~/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt > ~/CS3150/Scripts/HW1/textfiles/Titles.txt
or even
< ~/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt ~/Medline2012/getDocs.mps > ~/CS3150/Scripts/HW1/textfiles/Titles.txt
You either need to cat your .txt file, to pass the contents of it to the script via the pipe,
cat /home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt | /home/mumps/Medline2012/getDocs.mps > output
or, depending on what's in the script, it might need to go as a command line parameter, i.e.
/home/mumps/Medline2012/getDocs.mps /home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt > output
You are trying to execute your data file and feed the results to your script.
try
cat /home/mumps/CS3150/Script/HW1/textfiles/CardioAndPulmonary.txt | /home/mumps/Medline2012/getDocs.mps > /home/mumps/CS3150/Scripts/HW1/textfiles/Titles.txt
If you are still having trouble do a cd to the Medline2012 before you execute getDocs.mps. The reason is because when you access the getDoc.mps it calls to open the osu.medline database. This will cause a "file error" because the call in getDoc.mps does not include the path to osu.medline.
EDIT: A lot of people are telling you that you need to "cat" which is wrong. getDoc.mps has its own printing. If it didn't it wouldn't be printing "file error" for you. I also saw that you said that it is breaking after the loop. Did you test to make sure it isn't at the opening of the file. You can check by adding and indicating word in between the quotes in the first printing of "file error". You could change it to something like "file error 1." I realize you probably know that I just like to be thorough.

How to execute shell script from LaTeX?

I'm trying to do the following in LaTeX:
\documentclass{article}
\begin{document}
\execute{/usr/local/bin/my-shell-script.sh}
\end{document}
The idea is to execute /usr/local/bin/my-shell-script.sh at the moment of .tex document processing and inject its output into LaTeX stream. Is it possible at all?
PS. It's possible through the package I've made: iexec
I would do something like the following (partially motivated by what Roman suggested): make your LaTeX file be
\documentclass{article}
\begin{document}
\input{scriptoutput.tex}
\end{document}
and generate the file scriptoutput.tex using
/usr/local/bin/my-shell-script.sh > scriptoutput.tex
You could encode this in a makefile if you want to have it run automatically when necessary. Alternatively, you could use the TeX \write18 command,
\documentclass{article}
\immediate\write18{/usr/local/bin/my-shell-script.sh > scriptoutput.tex}
\begin{document}
\input{scriptoutput.tex}
\end{document}
and I think that would automatically run the shell script each time you compile the document. The \immediate is necessary to ensure that the script is run when LaTeX encounters the command, rather than waiting until a page of output is written. (See this question for more on the shipout routine.)
As David pointed out, you can use \write18 to call external programs, then \input the resultant output file. However you will probably want to use \immediate\write18 to make sure the script is executed before calling the \input.
Alternatively, if you use newer versions of pdf(la)tex (after 1.40, I think), you can pipe the output directly into the document, by using a piped input command:
\documentclass{article}
\begin{document}
\input{|"/usr/local/bin/my-shell-script.sh"}
\end{document}
For either method you will need to enable external program calls. For TeXlive distributions, you need to call latex with the -shell-escape option, or for MikTeX, I believe the option is -enable-write18.
You can do this in TeX. This paper (PDF) shows you how to write and execute a virus within TeX. The same principles apply for executing a shell script. However in my opinion it is more practicable to write a Makefile, which runs before your LaTeX run and inserts the result.
On Ubuntu 11.10 GNU/Linux
pdflatex --enable-pipes --shell-escape mytexfile
with
%...
[This section currently is
\input{|"wc kmb-box.tex| tr -s ' ' | cut -d' ' -f 4"}
% 2000 characters are allowed here
\input{kmb-box}
%...
works nicely. ie, this uses wordcount (wc) to report how many characters are in the file kmb-box.tex, which is part of (included in) the document.
(btw If you wanted words rather than characters, just change the number in "-f 4")
Unless it is imperative that the script is run while LaTeX is running I would recommend just using make to run LaTeX and you script.
I have used that approach to add word counting for articles and including statistics on bibliographic references.
Let your script generate a .tex file and include that in you LaTeX source file.
Below is a snippet from one of my Makefiles:
TEX = /usr/texbin/pdflatex
PREVIEW = /usr/bin/open
REPORT = SimMon
REPORT_MASTER = $(REPORT).tex
TEX_OPTIONS = -halt-on-error
SimMon: $(REPORT_MASTER) countRefferedPages
$(TEX) $(TEX_OPTIONS) $(REPORT_MASTER)
#$(PREVIEW) $(REPORT).pdf
countRefferedPages: BibTeXPageCount
cat *.tex | support/BPC/build/Debug/BPC Castle.bib > litteraturTotal.tex
This is how I do it with my own iexec package:
\documentclass{article}
\usepackage{iexec}
\begin{document}
\iexec{/usr/local/bin/my-shell-script.sh}
\end{document}
When the output is not required, I can do just this:
\iexec[quiet]{/usr/local/bin/my-shell-script.sh}

Resources