Unexpected EOF? - bash

I have been trying to create a graph in GNUPLOT using Bash. As I understand it, my following code should input the following lines into the gnuplot command until it reaches an EOF. I then send the "set" lines and "plot" line to gnuplot and follow it up with an EOF, which should end the input into the gnuplot command.
for FILE in ./tempFolder*.done; do
gnuplot <<EOF
set datafile separator ","
set xlabel "Hour"
set ylabel "Temperature"
set term png
set output "${FILE}.png"
plot "${FILE}" using 1:3 with errorbars title "Temperature/Time"
EOF
done
However, I get the following error message: "Syntax error: end of file unexpected (expecting "done")"
When I type try this in Bash outside of the script, it seems to work properly. Anyone have any pointers as to what I'm doing wrong?

You cannot indent the closing EOF; it has to be at the beginning of the line.
If you use <<-EOF instead of <<EOF, the shell will strip any leading tabs from each line of the here document, including the closing EOF.

Related

GNUPLOT : A better way of piping data into gnuplot script

I have a gnuplot script like this (simplified)
reset session
set terminal pngcairo enhanced font "Times,25" size 800,400
filename = ifilename
stats filename nooutput
N = STATS_columns
M = STATS_records
set angles degrees
set size square 1.25,1
set output ofilename
# does some stuff
...
...
...
set parametric
plot \
for [i=2:N] filename u (posX($0, column(i))):(posY($0, column(i))) w p ps 1.2 pt 7 lc rgb lcolor(i-2)
What I want to do is define ifilename (input file) and ofilename (output file) via a shell script.
So I thought the -e command might just be the one for the job.
So for the gnuploat part of the script I wroth this
gnuplot -e "ifilename='data/points_data1.dat'; ofilename='plot1'" chart.gp
but it threw the error
"chart.gp" line 8: undefined variable: ifilename
which refers to this line
filename = ifilename
I thought maybe that's because it's having some trouble parsing two = signs so I removed that line and rewrote my shell script like this
gnuplot -e "filename='data/points_data1.dat'; ofilename='plot1'" chart.gp
but this time it threw the following error
"chart.gp" line 8: undefined variable: filename
What actually worked was this
echo "data/points_data$i.dat" | gnuplot chart.gp
where I replaced the line filename = ifilename with
FILE = system("read filename; echo $filename")
and every instance of filename with FILE in .gp script.
But I'm not sure how to use that syntax to also define the output file.
So I was wondering, is there a better way of piping shell input into gnuplot script?
Your original command almost worked. The invocation
gnuplot -e "ifilename='data/points_data1.dat'; ofilename='plot1'" chart.gp
correctly defined the input and output file names. But then you clobbered them inside the chart.gp script by issuing the command
reset session
which clears all variable definitions including the ones you specifically wanted. Remove that line from the script and you should be fine. If the intent of the "reset session" command was to make sure that no system-wide or private initialization file is used, then replace it with a "-d" on the command line:
gnuplot -d -e "ifilename='data/points_data1.dat'; ofilename='plot1'" chart.gp
FILE = system("read filename; echo $filename")
is actually fine.
If you want to pipe the output to some file you can just omit set output "something.png"
and instead you could just send the .png output directly to stdout by running a script like this
#!/usr/bin/env gnuplot
reset session
set terminal pngcairo enhanced font "Times,25" size 800,400
...
then you can pipe that output to a .png file like this
./chart.gp > mypng.png
So the final command would look something like this
echo "data/points_data$i.dat" | gnuplot chart.gp > plot$i.png

Bash script sourcing config file but can't use vars in arithmetic

This is killing me. I have a config file, "myconfig.cfg", with the following content:
SOME_VAR=2
echo "I LOVE THIS"
Then I have a script that I'm trying to run, that sources the config file in order to use the settings in there as variables. I can print them out fine, but when I try to put one into a numeric variable for use in something like a "seq " command, I get this weird "invalid arithmetic operator" error.
Here's the script:
#!/bin/bash
source ./myconfig.cfg
echo "SOME_VAR=${SOME_VAR}"
let someVarNum=${SOME_VAR}
echo "someVarNum=${someVarNum}"
And here's the output:
I LOVE THIS
SOME_VAR=2
")syntax error: invalid arithmetic operator (error token is "
someVarNum=
I've tried countless things that theoretically shouldn't make a difference, and, surprise, they don't. I simply can't figure it out. If I simply take the line "SOME_VAR=2" and put it directly into the script, everything's fine. I'm guessing I'll have to read in the config file line by line, split the strings by "=", and find+create the variables I want to use manually.
The error is precisely as indicated in a comment by #TomFenech. The first line (and possibly all the lines) in myconfig.cfg is terminated with a Windows CR-LF line ending. Bash considers CR to be an ordinary character (not whitespace), so it will set SOME_VAR to the two character string 2CR. (CR is the character with hex code 0x0D. You could see that if you display the file with a hex-dumper: hd myconfig.cfg.)
The let command performs arithmetic on numbers. It also considers the CR to be an ordinary character, but it is neither a digit nor an operator so it complains. Unfortunately, it does not make any attempt to sanitize the display of the character in the error message, so the carriage return is displayed between the two " symbols. Consequently, the end of the error message overwrites the beginning.
Don't create Unix files with a Windows text editor. Or use a utility like dos2unix to fix them once you copy them to the Unix machine.

Here document notations [duplicate]

This question already has answers here:
here-document gives 'unexpected end of file' error
(10 answers)
Closed 2 years ago.
I cannot find much explanation regarding a notation in here documents. In my shell script, I am plotting a file with gnuplot.
This code works:
gnuplot <<- EOF
set xlabel "square dimension (inches)"
set ylabel "mean survival time (seconds)"
set term png
set output "${plot_file}.png"
plot "beetle.dat" using 1:2
EOF
However, if I do not include the dash in <<- and just use <<, this code does not work and I get the following error:
./myscript: line 118: warning: here-document at line 104 delimited by end-of-file (wanted `EOF')
./myscript: line 119: syntax error: unexpected end of file
This question might have been asked before, however due to special characters not being recognized, I cannot search for it.
When you say "this code", is it that code - or is it indented ?
Heredocs by default look for a line containing ONLY the delimiter, so no leading tabs or spaces. What the "-" does is remove leading tabs, so you can indent the heredoc (both content and delimiter) prettily in line with the rest of your code.
So if your delimiter is actually indented in the code, it will only be found with the "-"
See 3.6.6 in https://www.gnu.org/software/bash/manual/html_node/Redirections.html

Echo variable defined as result from command line resets cursor position

If I run this script:
#!/bin/bash
HOSTNAME=$(< ds.tmp)
echo "Hello${HOSTNAME}!"
TEST="1.2.3.4"
echo "Hello${TEST}!"
With the contents of ds.tmp only an ip address (say 1.2.3.4), the result is:
!ello1.2.3.4
Hello1.2.3.4!
So after I print a variable that is assigned by a $(...), the cursor position is reset and it overwrites all text.
Why is this? I have looked everywhere but cannot find a reference this anywhere...
Your ds.tmp file has CR-LF as its line breaks. As a result, ${HOSTNAME} contains 1.2.3.4\r, not just 1.2.3.4.
Unix text files should just use LF as their line breaks. Use dos2unix to fix it.
Try this:
HOSTNAME=$(tr -d "\r" < ds.tmp)

Gnuplot: One plot per file

I'm trying to plot the 1st and 3rd columns of multiple files, where each file is supposed to be plotted to an own output.png.
My files have the following names:
VIB2--135--398.6241
VIB2--136--408.3192
VIB2--137--411.3725
...
The first number in the file name is an integer, which ranges from 135-162. The second number is just a decimal number and there is no regular spacing between the values.
Basically I want to do something like this
plot for [a=135:162] 'VIB2--'.a.'--*' u 1:3 w l
although this doesn't work, of course, since the ' * ' is just the placeholder I know from bash and I don't know, if there is something similar in gnuplot.
Furthermore, each of the files should be, as already said above, plotted to its own output.png, where the two numbers should be in the output name, e.g. VIB2--135--398.6241.png.
I tried to come up with a bash script for this, like (edited):
#!/bin/bash
for file in *
do
gnuplot < $file
set xtics 1
set xtics rotate
set terminal png size 1920,1080 enhanced
set output $file.png
plot "$file" u 1:3 w l
done
but I still get
gnuplot> 1 14 -0.05
^
line 0: invalid command
gnuplot> 2 14 0.01
^
line 0: invalid command
...
which are actually the numbers from my input file. So gnuplot thinks, that the numbers I want to plot are commands... ?? Also, when the end of the file is reached, I get the following error message
#PLOT 1
plot: an unrecognized command `0x20' was encountered in the input
plot: the input file `VIB2--162--496.0271' could not be parsed
I've seen a few questions similar to mine, but the solutions didn't really work for me and I cannot add a comment, since I do not have the reputation.
Please help me with this.
gnuplot < $file starts gnuplot and feeds it the content of $file as input. That means gnuplot will now try to execute the commands in the data file which doesn't work.
What you want is a "here document":
gnuplot <<EOF
set xtics 1
set xtics rotate
set terminal png size 1920,1080 enhanced
set output $file.png
plot "$file" u 1:3 w l
EOF
What this does is: The shell reads the text up to the line with solemn EOF, replaces all variables, puts that into a temporary file and then starts gnuplot feeding it the temporary file as input.
Be careful that the file names don't contain spaces, or set output $file.png will not work. To be safe, you should probably use set output "$file.png" but my gnuplot is a bit rusty.

Resources