This question already has answers here:
How do I set an environment variable in Perl?
(5 answers)
Closed 6 years ago.
I was trying to set shell variable name with help of perl script.
But it was not running fine.
system("variable_name=\"variable_value\"");
`variable_name=\"variable_value\"`;
Any one tell me why it was not working.
Actually my question was little bit different.
I want to know how to set environment "setenv" with help of perl script.
I have tried
$ENV{"VARIABLE_NAME"} = "home\/path_1\/path_2\/path_3";
Then I fire command echo $VARIABLE_NAME then it is not giving me path that I set from perl script.
Thanks
You have no need to run a new shell to set an environment variable; indeed, doing so is counterproductive, since the value doesn't outlive the shell in which it's assigned (except through any surviving children of that shell which may have inherited the value).
You can simply set an environment variable directly in your perl:
$ENV{"variable_name"} = "variable_value"
Any subsequent shell you start from your perl script will see this.
It was working. The problem is that the next system command runs a new shell which doesn't know about variables set in the first shell.
system 'x=value; echo $x'; # Outputs "value".
system 'echo $x'; # Empty line - the shell with $x doesn't exist anymore.
Related
I am setting env variables using *.csh file to current terminal. When I use system("/bin/tcsh *.csh") in the perl script, the *csh file executing but not setting any env variables to current terminal.
When I use system("/bin/tcsh *.csh") in the perl script, the *csh file executing but not setting any env variables to current terminal.
sub veloce_env_setup_sub {
printf "\n\n\t -veloce_env_setup option enabled\n";
system("/bin/tcsh /proj/I2BZA1/users/ssudi/SCRIPTS/veloce_env/vlab_4p4p0/veloce_setup.csh");
}
Expected: env variables should set to current terminal after sourcing *.csh file.
Actual results: only prints are comming but not setting env variables to current terminal.
perldoc -q environment:
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 any children created after the change. There is shell magic that may allow you to fake it by eval()ing the script's output in your shell; check out the comp.unix.questions FAQ for details.
In your code the problem appears twice:
system spawns tcsh, which runs a script that sets environment variables. These environment variables only exist within the tcsh process. When system returns (i.e. when tcsh exits), the environment of the child process is gone.
Even if you managed to modify the environment of the perl script (which you can do by assigning to %ENV), that wouldn't affect the parent shell that perl was started from.
This can now be done with Env::Modify.
use Env::Modify qw(:tcsh source);
sub veloce_env_setup_sub {
printf "\n\n\t -veloce_env_setup option enabled\n";
source("/proj/I2BZA1/users/ssudi/SCRIPTS/veloce_env/vlab_4p4p0/veloce_setup.csh");
}
The environment of a child process doesn't affect the environment of the parent process. That is, a process that you start doesn't change the environment of the thing that started it.
If you want to set up the environment for a Perl script, you have some options. Which one works best for you depends on what you are trying to do.
Set up the options inside Perl. Instead of using a shell program, do it all in Perl by setting values in the %ENV hash. This works well if you just need it for that program. It's likely that whatever you are doing in tcsh you can do it Perl.
Instead of calling the shell script from Perl, call your Perl program from the shell script. Now the shell script is the parent process and the child process (the Perl program) inherits the parent's environment.
#!tcsh
setenv SOME_VALUE foo
perl my_program
In a child process, you could print the environment and read that from the parent process. You'd parse it and convert it appropriately. This is what the Env::Modify module does, but I wouldn't want that as my first option.
You can't access environment variables in a process that have been set by a child process. It's a fundamental property of how processes work.
You can set %ENV{'your_choice'} = 'as you like'; inside Perl.
Sure, it looks like a little bit hartverdrahtet (yt), but it works great again. So the environmental is mental just inner the mind of top instanced script and closed and removed on closing it.
Another way is calling system("set VARIABLE=VALUE");
Here the variable lefts after closing until next reboot.
In my fish shell script 'hoge.fish`, I have a code to set envs.
#!/usr/local/bin/fish
set -x HOGE "hello"
but after I exec this script the env is not set correctly and outputs nothing.
./hoge.fish
echo $HOGE
I've tried these code but none of these worked.
set -gx HOGE "hello"
set -gU HOGE "hello"
how can I fix this?
OS: macOS High Sierra 10.13.6
fish version: 2.7.1
iTerm2: 3.2.0
When you ran the script, it probably set the environment variable correctly, but only in the process that was created when you ran the script....not in the parent session you ran the script from! When the script exited, the process and its environment were destroyed.
If you want to change the environment variable in your current environment, depending on what interactive shell you're using, you can use a command like source hoge.fish, which will execute the commands in your current session rather than a subprocess, so the environment variable changes will persist.
While sourceing, as in the original answer is definitely the correct mechanism, a comment from the OP to that answer mentioned that they would still prefer a solution that could be executed as a script.
As long as the variables are exported (set -x) in the script, it's possible (but still not necessarily recommended) to do this by execing into another fish shell inside the script:
#!/usr/bin/env fish
set -gx HOGE hello
exec fish
Executing ./hoge.fish will then have a fish shell with HOGE set as expected.
However, be aware:
This will result in two fish shell processes running, one inside the other. The first (parent) is the original fish shell. It will spawn a second (child) process based on the shebang line, which will then be replaced by the third instance from the exec line.
You can reduce the number of shells that are running simultaneously by starting the script with exec ./hoge.fish. That results in the shebang script replacing the parent process, and then being replaced by the exec line at the end of the script. However, you will still have run fish's startup twice to achieve what a simple source would have done with zero additional startups.
It's also important to realize the environment of the new shell will not necessarily be the same as that of the original shell. In particular, local variables from the original shell will not be present in the exec'd shell.
There are use-cases where these pitfalls are worth execing a new shell, but most of the time a simple source will be preferred.
Consider that if you run that from bash shell it will not export the variables with the -U option because it indicates to export to "fish universe" not outside.
If you stay inside fish's shell you still can do it like this:
#!/usr/local/bin/fish
set -Ux HOGE "hello"
And this is the result:
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
~/trash $ ./hoge.fish
~/tr ash $ echo $HOGE
hello
Remember to keep the first line so fish will interpret it properly.
This question already has answers here:
#ARGV is empty using ActivePerl in Windows 7
(4 answers)
Closed 9 months ago.
I'm running ActivePerl 5.8.8 build 822 on Win7 x64. We're working on a project that is about 60% C++, 15% perl, etc. The Perl is heavily used to link bits and pieces and various small utility applications together to create and pack our final data. So, for example, our VS2005 solution has post build events to create hard links to DLL's using a post build perl script which lives at some location on our development drive (it is part of PATH env var).
I found out quickly, that without explicitly putting "perl" to call the interpreter in-front of the postbuild.pl script call, it wouldn't accept command line arguments. I tested this further simply by going to the cmd window and doing the same with a "hello world" style perl script. No command line arguments were passed in when I say "bleh.pl arg1 arg2". But when I say "perl bleh.pl arg1 arg2" I get command line arguments.
When this failure occurs, perl reads zero command line arguments, and the #ARGV variable empty or null (whatever this crazy language does). So they're simply not passed in.
This is an issue because there are hundreds if not thousands of calls to perl scripts which I fear are not behaving correctly, and it is unreasonable to think I should have to prefix every .pl script invocation with perl explicitly, not to mention we're using version control and I don't want to commit all these garbage changes nor manage them in my stash.
PERL env var exists and points at the folder where the perl binary lives. As well as PATHEXT has .PL in it for perl scripts. Likewise, my PATH contains the folder entries to get to the scripts and to perl also.
Any help on how to figure this out would be immensely appreciated! Also, when I installed ActivePerl (I've done so many times now trying to figure this out). I allowed it to change my Path and associate file extensions in windows, which you would think would be the solution.
Thank you!
Your association is broken (incomplete). First, open a console and execute
assoc .pl
You'll get something like
.pl=SOMETHING
Then, execute
ftype SOMETHING
You should get something like
SOMETHING="C:\SOMEWHERE\bin\perl.exe" "%1" %*
but you'll get something like the following instead:
SOMETHING="C:\SOMEWHERE\bin\perl.exe" "%1"
To fix it, execute
ftype SOMETHING="C:\SOMEWHERE\bin\perl.exe" "%1" %*
I have a bluehost server setup and am trying to set the path in my perl program
print "Content-type: text/html\n\n";
my $output=`export PATH=\${PATH}:/usr/local/jdk/bin`;
my output1=`echo \$PATH`;
print $output1;
However it stil prints only the orginal $PATH. The /usr/local/jdk does not get added. Can anyone tell me what i am doing wrong?
You are creating a shell, executing a shell command that sets an environment variable in the shell, then exiting the shell without doing anything with the environment variable. You never changed perl's environment. That would be done using
local $ENV{PATH} = "$ENV{PATH}:/usr/local/jdk/bin";
Kinda weird to add to the end of the path, though.
Please note that ikegami's answer will only set the path in your local Perl-script, and will NOT change it for the shell that called your Perl script.
If you wish to change the path in the shell environment, so the next programs you run will also benefit from this change,
you will have to use 'source' or "dot-space" sequence,
or better yet - have this change to the path done in '.bashrc' or '.login' files.
I have a Korn shell script at a location like /opt/apps/abc/folder/properties.env. I can execute it from Unix bash using the dot command:
. /opt/apps/abc/folder/properties.env
This works.
I have a Perl script abc.pl from which I am calling the script properties.env. I tried the following different:
system('/usr/bin/ksh','-c', '. /opt/apps/abc/folder/properties.env');
/usr/bin/ksh -c /opt/apps/abc/folder/properties.env;
system('. /opt/apps/abc/folder/properties.env');
None of the above work. I don't want to use exec because I want to return to the Perl script. What am I doing wrong?
The environment changes will only last as long as the life of the ksh session spawned by the system command. If you want the environment changes to affect the Perl script, then you have to source that file before you launch the Perl program.
If you need those environment variables in your perl code, (not in the environment where you called perl), you can also read and parse that properties.env and set the environment in the %ENV variable.
e.g
$ENV{'ENV_VAR1'}=VALUE_OF_ENV_VAR1
using system() spawn another process, as the other poster said. changing environment in the child does not affect the parent.