I'm using Gnuplot as my back-end plotter and I often use the following setup :
#Filename : my_plot.gnuplot
set terminal pdfcairo [my_options]
set output 'my_plot.pdf'
....
coupled with a Makefile :
%.pdf : %.gnuplot
gnuplot $<
My question is simple : is there a command / way to refer to the name of the script inside the script (the equivalent of bash's $0) and set the output with a clever sprintf or equivalent ?
You cannot access the script name from gnuplot, but you can give a parameter when calling the script, which should work fine, especially when using Makefiles.
%.pdf: %.gnuplot
gnuplot -e "scriptname='$<'" $<
Related
I am working on Bash 5.0 from GNU repository. I wanted to find the place where Bash reads a string with ASCII colors and convert it to colors, like in the following case where it convert "Hello" to red:
root#ubuntu:~/Desktop/bash-5.0# ./bash
root#ubuntu:~/Desktop/bash-5.0# echo $BASH_VERSION
5.0.0(8)-release
root#ubuntu:~/Desktop/bash-5.0# ./bash -c 'echo -e "\033[31mHello\e[0m World"'
Hello World
I searched inside the source code and found two files that seems to be related:
bash-5.0/lib/readline/colors.c - link
bash-5.0/lib/readline/parse-colors.c - link
But they are not, they work only on the first time I load Bash and you need to write the following rows in the file ~/.inputrc for it to work:
set colored-completion-prefix on
set colored-stats on
Any idea where in the code Bash takes string like that "\033[31mHello" and convert it to red?
It's not the shell that's converting anything to colors, it is your terminal. The shell only outputs ANSI escape codes which are then picked up by the terminal.
Depending on your point of view and philosophical interpretations, \033[31mHello already is a colored string (for the shell, at least, it is)
I create a binary myBinary via cmake/CMakeLists.txt.
I would like to "include" default options on my binary.
In other words, I want my binary to be called with myBinary --option myopt even when I just run ./myBinary
How can I do that?
CMake does not have built-in support for you you want to do.
One solution is to do as #Youka said - change the source code of your program.
Another solution that I have used sometimes is to autogenerate a script that executes an executable:
# Create startup script
MACRO(GEN_START_SCRIPT binName)
# Generate content
SET(fileContent
"#!/bin/bash\n"
"\n"
"# This startup script is auto generated - do not modify!\n"
"\n"
"${binName} -a 23 -b 34 -c 976\n"
"\n"
)
# Write to file
SET(fileName ${CMAKE_CURRENT_BINARY_DIR}/${binName}.sh)
FILE(WRITE ${fileName} ${fileContent})
ENDMACRO()
Then call the macro after defining your executable:
ADD_EXECUTABLE(myBinary file1.c file.2)
GEN_START_SCRIPT(myBinary)
You can of course add other stuff to the script, like environment variables etc.
If you're in control of the sources and you want different default behavior... change the sources!
This is in no way a build system issue (CMake or otherwise).
How to programmatically get the name of current gnuplot script? I know that I can call gnuplot script from bash and get it file name but I am wondering if it is possible from inside gnuplot. My goal is to make something like:
date=system("date +%F_%T | sed 's/:/-/g'")
my_name=$0 # THIS IS HOW TO DO IT IN BASH
set term png
set output my_name.date.".png"
I've tried:
my_name=system("cat /proc/$$/cmdline")
but it returned sh instead of script name
Not quite an answer to your question, but this might help with what you want to do:
You can leave my_name unset in the script, and set it either inside gnuplot, just before you load the script (where you need to know the script name anyway):
my_name=...
load(my_name)
or set it when you invoke gnuplot from the shell:
$ gnuplot -e "my_name=${FILE}" ${FILE}
A few more things:
date=system("date +%F_%T | sed 's/:/-/g'")
can be replaced with
date=system("date +%F_%H-%M-%S")
(which is shorter and doesn't need to be parsed through sed) or without any forking at all:
date=strftime("%F_%H-%M-%S",time(0.0))
Using gnuplot version 5 you have access to the file called with load via the variable ARG0
Consider the script test.gp which contains only
print ARG0
Now, calling this with
gnuplot -e "load 'test.gp'"
prints you test.gp on the screen. With earlier versions you don't have access to a similar variable (also not when using call). For earlier versions you must stick to one of the solutions given by #chw21
I have a environment variable set with name $MY_ENV_VARIABLE.
How do I use this variable inside my makefile to (for example) include some source files?
LOCAL_SRC_FILES = $(MY_ENV_VARIABLE)/libDEMO.so
Something like above doesn't seem to work.
Note: in my case this is needed for building with the Android NDK but I guess this applies to make in general.
Just to add some information...
The syntax to access the environment variable in make is like other variables in make...
#export the variable. e.g. in the terminal,
export MY_ENV_VARIABLE="hello world"
...
#in the makefile (replace before call)
echo $(MY_ENV_VARIABLE)
This performs the substitution before executing the commmand. If you instead, want the substitution to happen during the command execution, you need to escape the $ (For example, echo $MY_ENV_VARIABLE is incorrect and will attempt to substitute the variable M in make, and append it to Y_ENV_VARIABLE)...
#in the makefile (replace during call)
echo $$MY_ENV_VARIABLE
Make sure you exported the variable from your shell. Running:
echo $MY_ENV_VARIABLE
shows you whether it's set in your shell. But to know whether you've exported it so that subshells and other sub-commands (like make) can see it try running:
env | grep MY_ENV_VARIABLE
If it's not there, be sure to run export MY_ENV_VARIABLE before running make.
That's all you need to do: make automatically imports all environment variables as make variables when it starts up.
I just had a similar issue (under Cygwin):
Running echo $OSTYPE on the shell prints the value, but
running env | grep OSTYPE doesn't give any output.
As I can't guarantee that this variable is exported on all machines I want to run that makefile on, I used the following to get the variable from within the makefile:
OSTYPE = $(shell echo $$OSTYPE)
Which of course can also be used within a condition like the following:
ifeq ($(shell echo $$OSTYPE),cygwin)
# ...do something...
else
# ...do something else...
endif
EDIT:
Some things I found after experimenting with the info from jozxyqk's answer, all from within the makefile:
If I run #echo $$OSTYPE or #echo "$$OSTYPE" in a recipe, the variable is successfully expanded into cygwin.
However, using that in a condition like ifeq ($$OSTYPE,cygwin) or ifeq ("$$OSTYPE","cygwin") doesn't expand it.
Thus it is logical that first setting a variable like TEST = "$$OSTYPE" will lead to echo $(TEST) printing cygwin (the expansion is done by the echo call) but that doesn't work in a condition - ifeq ($(TEST),cygwin) is false.
I am writing a shell script to set the environment variables whose values are available in a file. Below is the shell script I wrote,
VARIABLE_FILE=env-var.dat
if [ -f ${VARIABLE_FILE} ] ; then
. ${VARIABLE_FILE}
if [ ! -z "${TEST_VAR1}" ] ; then
export TEST_VAR1="${TEST_VAR1}"
fi
if [ ! -z "${TEST_VAR2}" ] ; then
export TEST_VAR2="${TEST_VAR2}"
fi
fi
The above code works only in bash shell, since I have used export command to set the environment variable and it fails if I used it with any other shell. Is there is any command to set the environment variable which works in any shell ?
"Fancier" shells like bash and zsh permit you to set a variable and export it as an environment variable at the same time like so:
export FOO=bar
With a standard POSIX bourne shell, the equivalent is achieved by doing it in two commands:
FOO=bar
export FOO
Note that once you've exported a variable, you can reset it to a different value later in the script and it's still exported (you don't need to export it again). Also, you can export several variables at a time:
FOO=bar
BAZ=quux
export FOO BAZ
You mentioned tcsh in your comment, but csh and derivatives are completely different from bourne-based shells (and not recommended for use!). You can rarely make a shell script compatible with both sh and csh at the same time. For csh, look into setenv
If you really want this to happen, it can be done, but it's tricky. One way to do it is to use awk to output the correct syntax and evaluate the text coming back from awk. To share a single environment variable value file between major sh and csh flavors, the following command in a file will import a variable value file to the environment: (yes, yes, it's one huge line, due to the inflexible way that some shells treat the backticks. If you didn't mind having a .awk file too, you could use awk -f...)
eval `awk '{ var = $1; $1=""; val=substr($0,2); if ( ENVIRON["SHELL"] ~ /csh$/) { print "setenv", var, " \"" val "\";" } else { print var "=\"" val "\"" ; print "export", var }}' $HOME/env_value_file`
The variable value file is in this format:
FOO value for foo
BAR foo bar
BAZ $BAR plus values $FOO
Design notes for educational purposes:
In awk, there's no easy way of accessing fields 2-NF, so if there
could be spaces in our variable values we need to modify $1 to get
$0 to be close to get the value we want.
To get this to work, since a SHELL variable is always set, but not as an
environment variable and not with a consistent capitalization, you have to wet
a SHELL environment variable from the shell's value as below.
as an environment variable before you use the script.
Also, if you want the new environment values to be present after the import
environment script you need to source the environment script.
If a shell doesn't do eval well, you'll have to tweak the script.
For bourne shell flavors (bash, sh, ksh, zsh):
export SHELL
. import_environment
For csh flavors: (shell variable tends to be lower case in csh shells)
setenv SHELL "$shell"
source import_environment