using setenv in makefile - linux

I am trying to use setenv variable in my makefile but when I execute my make file it gives setenv: command not found.
How can I use it?
Actually I wanted to run a shell script which sets multiple environment variables.
Since the list is very huge I dont have an option except to use the scripts. I cant set them manually like
abcd:= /xx/yy/zz
Please suggest.
P.S. the same command
setenv xxx yyy works very well in shell
it just fails when I use in makefile directly or makefile with a script having this command.
'

Why do not you use export command ?

Running the script to set the environment variable will not work as the shell run a separate process & will not reflect in your current shell. You will need to source the shell script. You can use source or . based on your shell. Following is a sample for your reference where setvar.sh sets a variable & print.sh prints it; in the Makefile (mkfile) setvar.sh is being sourced using .
$ cat setvar.sh
export TEST=ABC
$ cat print.sh
echo $TEST
$ cat mkfile
test:
. ./setvar.sh && ./print.sh
.SILENT:test
$ make -f mkfile
ABC
You can also include I guess for example,
$ cat mkfile2
include setvar.sh
test:
./print.sh
.SILENT:test
$ make -f mkfile2
ABC
Hope this helps!

Look at
make -e
and Communicating Variables to a Sub-make

I think setenv is not a builtin to the sh shell. If you are using GNU Make that is the default shell used. In your situation you probably want to use a different shell, like bash. You do this by setting the SHELL variable in the makefile to what you want like:
SHELL := /usr/bin/bash
For more information checkout this section of the GNU Make manual. It details the different behavior of the SHELL variable and how it is, or isn't inherited from the shell make is invoked from on different platforms.
EDIT: I agree with the implication of the other posters that you are probably not setting enviroment variables the way you think you should be and would not be using the setenv command at. I am just responding to your original question. To learn about variables in make files checkout these other sections in the GNU Make manual.

export MY_VAR := "/package/your_path"

Related

How to reload /etc/environment from shell script

So I have this shell script that checks and then concats an environmental variable to /etc/environment, then reloads the file without having to logout/login:
#!/bin/sh
portvar="PORT=5000"
echo $portvar
grep -q $portvar /etc/environment && echo "EV already in" || echo $portvar >> /etc/environment
set -a; source /etc/environment; set +a;
When I run it, I get the error ./test.sh: 5: ./test.sh: source: not found. However, if I run set -a; source /etc/environment; set +a; directly in the terminal it updates the environmental variable just fine. I have no idea what the set command does, I just found it in another stack overflow question.
Any idea why it runs in the terminal directly but not in the .sh file?
Thanks
/bin/sh on your system is likely some shell that isn't bash and doesn't implement the source command. On my Ubuntu 20.04 system /bin/sh is actually dash.
The source command is not defined by POSIX as part of the shell command language nor is it one of the required special built-in utilities. It's a non-standard feature provided by bash. However, the . command, which does the same thing, is specified by POSIX.
So you can use . instead, e.g. . /etc/environment. Or if you want to keep using source, then you need to have your script run by bash or some other shell that supports it, by changing the shebang line to #!/bin/bash.
There is a tool called checkbashisms that can help you find unintentional uses of bash-specific features in your scripts. When run on your script, it flags this:
possible bashism in foo.sh line 5 (should be '.', not 'source'):

Setting environment variable in /usr/bin/env hangs process on Linux

While the man for env on Linux seems to indicate that you can set new environment variables before executing a command. Unfortunately, when I set new variables in a file's shebang on Linux systems, the file never executes.
#!/usr/bin/env VAR1=foo bash
echo $VAR1
When I execute this file on a CentOS or Ubuntu machine, it just sits there.
$ ./shell-env.sh
<nothing happens>
What I find particularly bizarre is this works perfectly fine on OS X with BSD env.
$ ./shell-env.sh
foo
$
Is this just a difference between BSD env and Linux env? Why do the man pages for Linux seem to say it should work the same way as on BSD?
P.S. My use case here is to override the PATH variable, so I can try to find a ruby on the system but that's not on the PATH.
Thank you in advance!
There's a way to manipulate the environment before executing a Ruby script, without using a wrapper script of some kind, but it's not pretty:
#!/bin/bash
export FOO=bar
exec ruby -x "$0" "$#"
#!ruby
puts ENV['FOO']
This is usually reserved for esoteric situations where you need to manipulate e.g. PATH or LD_LIBRARY_PATH before executing the program, and it needs to be self-contained for some reason. It works for Perl and possibly others too!

linux issue setenv command not found

I develop a Tcl/Tk script tool in Linux. In order to run the tool, every time I need to set the environment variable like this in shell:
setenv LD_LIBRARY_PATH /opt/lsf/9.1/linux2.6-glibc2.3-x86_64/lib:/abc/software/new_2015/GE/tcl_tk/lib64:/abc/software/new_2015/GE/tcl_tk/lib64
and then use "wish" interpreter to launch my tool:
/abc/software/new2015/GE/tcl_tk/bin/wish mytool.tk
To make it a little easy to use, I want design a shell script "abc_wish" and put the above command inside:
#!/bin/sh
setenv LD_LIBRARY_PATH /opt/lsf/9.1/linux2.6-glibc2.3-x86_64/lib:/abc/software/new_2015/GE/tcl_tk/lib64:/abc/software/new_2015/GE/tcl_tk/lib64
wish="/abc/software/new2015/GE/tcl_tk/bin/wish"
exec $wish $#
And then I need just run:
./abc_wish mytool.tk
But error message shows that setenv command not found!I am totally new to such system issues, need some help about these stuffs. Hope I have shown the issue clearly.
setenv is a csh command, not a sh command. The equivalent in bash is export:
#!/bin/sh
export LD_LIBRARY_PATH=/opt/lsf/9.1/linux2.6-glibc2.3-x86_64/lib:/abc/software/new_2015/GE/tcl_tk/lib64:/abc/software/new_2015/GE/tcl_tk/lib64
exec wish "$#"
You should also put $# in quote, to ensure proper re-quoting of the expansion.

How to source file from bash script

I'm trying to source a file with an environment variable from my bash script, but it doesn't work.
This is the content of my script (test.sh), which is located in ~/scripts/test.sh.
#!/bin/bash
FILE_NAME=/tmp/source_file
touch $FILE_NAME
echo "export TEST=\"test\"" > $FILE_NAME
source $FILE_NAME
Then I use alias in my ~/.bashrc.
alias testScript=~/scripts/test.sh
But when I use my script testScript, it didn't set the environment variable.
You need to use:
alias testScript=". ~/scripts/test.sh"
to source the file. Or you can use source in place of ., but I don't much like C shells so I don't use C shell notations such as source.
Environment variables only flow downstream in the process tree.
When you type testScript to a bash process, it creates a child process and execs /bin/bash or whatever is set by #!
Any environment variables set there remain only with the child process. Export causes the variables to be copied to additional grandchildren (children of that child) that might be spawned from that child.
Nothing can copy back to a parent. You need to use source instead of running the file. See Jonathan's answer.
You could try editing the files ~/.bashrc or ~/.login to set enviornment variables you need frequently.
See also https://superuser.com/q/153371 and https://superuser.com/questions/18988/difference-between-a-b-and-export-a-b-in-bash for more explanation of export in bash.
None of the other methods worked for me [source /path/to/file vs . ./path/to/file, alias, etc...], until, thanks to this tutorial I found that using the:
#!/usr/bin/env bash shebang
instead of the simpler #!/usr/bin/env one lets arguments pass on to the interpreter, which I think is the key here – see this document for more info.
In any event, if source commands in any form aren't working for you, try checking your shebang, that might be the problem :)

How do I import environment settings into my Perl program?

I have a script whose content simply exports a variable in linux.
export LD_LIBRARY_PATH=....
I want to run this script in my Perl script so whoever is running my Perl script will have their LD_LIBRARY_PATH set. Can i just do this in the beginning of my Perl script:
#!/usr/bin/perl -w
system(". /myfolder1/myfolder2/myScript.sh");
#!/bin/sh
. /myfolder1/myfolder2/myScript.sh
exec perl -wxS "$0" "$#"
#!/usr/bin/perl -w
# .. the rest of your script as normal
When you run this, it will first be executed by /bin/sh, which is capable of loading myScript.sh into the local environment. sh then execs Perl, which is told to continue from the following line.
This won't work. To change the environment inside your Perl script (and to change the environment that will be passed on to commands run from inside your Perl script), change the %ENV variable.
$ENV{"LD_LIBRARY_PATH"} = ... ;
This won't work. There is no way for a subshell to manipulate the environment of the parent process.
But you could make your script echo the string you want to set as LD_LIBRARY_PATH and then from within your Perl script you could do something like that:
$ENV{LD_LIBRARY_PATH} = `path/to/your/script.sh`;
Of course, a bit of error checking might also be a good idea.
No. Your environment changes made in a child cannot affect the parent. This means running a script will not affect perl. Also perl will not affect the shell from which it was called. You can edit the environment inside perl by changing the special variable %ENV. If there's some kind of unreproducible calculation done in that script, maybe the script should just echo the setting and perl can pick that up on STDOUT and use it.
I {changed directory, modified my environment} in a perl script. How come the change disappeared when I exited the script? How do I get my changes to be visible?
Unix In the strictest sense, it can't be done -- the script executes
as a different process from the shell
it was started from. Changes to a
process are not reflected in its
parent, only in its own children
created after the change.
I had a similar problem a few years ago and whipped up a little module, Env::Sourced, that should do the trick.
use Env::Sourced qw(/myfolder1/myfolder2/myScript.sh);
...
Another option (other than making the changes directly in Perl's %ENV) is to make the changes you want a Perl module, so that you can say:
use MyEnvironment;
and have it modify your environment in all your scripts. It would make it simple to make changes after the fact that will not require editing every script.
The module itself will be simple, something like this:
package MyEnvironment;
$ENV{LD_LIBRARY_PATH} .= ":/some/path/you/want/appended";
# Any other changes you want here.
1;
That won't work. An (unpleasant) alternative might be to replace /usr/bin/perl with a shell script that first executes your script and then executes the perl executable.
This can't be done in the way you're trying to do this.
It either needs a wrapper shell script that sets LD_LIBRARY_PATH and then calls your perl script, or any user executing the script needs to have LD_LIBRARY_PATH set correctly in the first place.
If doing the latter, then this can be managed globally by editing /etc/profile and /etc/cshrc (for ksh, sh, bash, csh and tcsh) shells. You can then test for the value of LD_LIBRARY_PATH in your script and if not set/set incorrectly then print a friendly message to the user. Alternatively individual users can set this in their local .profile/.cshrc files.
Note: you haven't given any information about the environment or useres that might run this, so there's also the possibility that users may set LD_LIBRARY_PATH to something they need. If you do check LD_LIBRARY_PATH for a "good" value in your script, then keep in mind that several paths may have been specified, so you will need to parse this environment variable properly.
If you can find the right place in your perl script, this works as in my example:
$ENV{"LD_LIBRARY_PATH"} = "/oracle/product/10g/lib";
And it didn't require me to call another script to set the env var.
The Env::Modify module addresses this issue, at least for POSIX-y platforms:
use Env::Modify 'source';
source("/myfolder1/myfolder2/myScript.sh");
... environment settings from myScript.sh are now available to Perl ...

Resources