I'm a newbie to Perl and Tcl. I'm trying to pass a variable from a Perl script to a Tcl script. I declared the variable as environment variable and trying to pass. But no results. Please find the code below:
Perl side:
$ENV{'output_directory_final'} = "./$Image_name/$Date_release/final";
Tcl side:
set out_path ${output_directory_final};
But, this is not working. Can anyone give any other ideas?
By special dispensation, the global array env in Tcl contains the values of the environment variables for the process. In your case, try something like:
set out_path $env(output_directory_final)
Be mindful that if you are inside a proc, then a global env command is necessary to obtain local access to the variable.
Related
In powershell, how can I...
explicitly define all the env vars for the next command?
I don't want any system env vars if possible,
After this command runs I dont want anything we have done to affect further processes in the shell.
As an example, in python we have the equivalent ability in Popen to pass a dictionary of the full environment to the subprocess, and I'm hoping there might be something similar in Powershell.
I think this link explains what you need: Windows user environment variable vs. system environment variable
[Environment]::GetEnvironmentVariable("TEMP", "Machine")
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.
So, in powershell, I type
$ Set-Variable FOO
Then, in my makefile, I have
.PHONY: show-foo
show-foo:
#echo ${FOO}
It outputs a blank line.
I've tried using system variables like $profile, none of the environment variables seem to be passed into the makefile.
can someone tell me what I'm doing wrong here?
On windows 10, using make 4.2.1
Set-Variable sets a shell variable, but does not modify the environment (just like var="val" in sh without exporting would). Instead use
$env:FOO="VALUE"
to manipulate the environment.
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.
Can I set PERL5LIB in a separate script and call that script in other scripts? How do I do it? And how would it affect the script in which it is used?
Setting PERL5LIB at runtime will not affect Perl's search path. You need to export the variable before executing the interpreter.
Alternatively you can modify #INC at compile time (also possible to do in a separate script/module):
BEGIN { unshift #INC, "/path/to/dir" }
This is what the lib pragma does.
You'd do this via 'use lib' rather than manipulating the environment:
use lib '/home/perl5';
That could be in a separate file that you 'require' in.
PERL5INC is a shell environment variable, so you wouldn't set it inside your Perl program (normally) but instead specify it before invoking Perl. The below is a shell command where I've used PERL5LIB to instruct prove to find a Perl module residing in ~/OnePop:
$ PERL5LIB=~/OnePop prove -l t
... PERL5LIB is unset here ....
When a command is preceded by a variable assignment like this, the shell sets and exports the variable (PERL5LIB) to that command, but after that the variable will be unset again. You can also set the variable in the shell, so that all subsequent commands will inherit it.
$ export PERL5LIB=~/OnePop
...
$ prove -l t
... PERL5LIB continues to be set here ...
If you forget the export keyword in the above example (i.e. assigns the value using PERL5LIB=~/OnePop on a separate line) the variable will be set in the shell, but it will not be inherited by any commands you run (meaning that prove will not be able to see it).
Finally, if you wanted to set the environment PERL5LIB variable from inside a Perl program you'd have to write it like this:
$ENV{PERL5LIB} = glob("~/OnePop"); # glob() expands the tilde
system(qw( prove -l t ));
Though, as other have pointed out, if you want to specify the include path from inside Perl it is easier/better to use use lib $PATH.
PERL5INC is an environment variable. Environment variables are only inherited from parents to their children and can't (easily) be set the other way around. If you want to store extra search paths in an external file I suggest you make it a simple list of paths and write a simple loop to read each path from the file and manipulate #INC in the current process. If you want this to be done early at compile time you'll have to use a BEGIN {} block.
For example
BEGIN{
open(INCFILE,"<","my.inc.file") or die($!);
foreach(<INCFILE>){
push #INC,$_;
}
close(INCFILE);
}
Alternative to PERL5LIB:
You could instead install the latest version of Perl 5 available (in a non-system location, of course). After you have used a module file or done whatever is necessary to make the new perl and cpan executables visible to your shell, you can use cpan to install all the modules you need. I have sometimes done this for individual applications in a similar vein to using Python Virtual Environments.