This question already has answers here:
Is there a way to change the environment variables of another process in Unix?
(12 answers)
Closed 9 years ago.
Consider the following Ruby code
sleep 10
puts "Foo is #{ENV['foo']}"
Saving this file to envtest.rb
Running this from the shell:
export foo=bar
ruby envtest.rb &
export foo=baz
( ... 10 seconds later ... )
=> Foo is bar
It appears that the environment is evaluated when the ruby interpreter is launched. Is it possible to update environment variables during execution and have those changes reflected in running processes? If so, how?
You can change the value during runtime - from inside the ruby script - using:
ENV['VARIABLE_NAME'] = 'value'
There is no option to change environment values from outside the process after it has been started. That's by design, as the environment will be passed at process startup.
No. This is not possible. One process can never directly manipulate the environment of a different already-running process. All you can ever do is set the environment on unborn children, then create them.
The only other approach is via active, negotiated communication back to the parent. That’s why the output from tset(1) (that is, of tset -s) is always evaluated by the parent.
Related
This question already has an answer here:
JMeter - submit JMeter function inside a script (JSR223 element)
(1 answer)
Closed 1 year ago.
I use groovy to write a script. In the screenshot, No. 1 works, No. 2 doesn't work, No. 3 works. It's normal to print No. 1 separately. No. 2 and No. 3 are written in a custom function. The parameter passed in by No. 2 is still ${re} instead of value
Don't inline JMeter Functions or Variables into Groovy scripts, your "No 1" and "No 3" work because they're GStrings and your "No 2" conflicts with JMeter Functions and/or Variables syntax.
So I would recommend moving your function into "Parameters" tab like:
Also according to JSR223 Sampler documentation:
Or Use Script Text and check Cache compiled script if available property.
When using this feature, ensure your script code does not use JMeter variables or JMeter function calls directly in script code as caching would only cache first replacement. Instead use script parameters.
So if your ${secretKey} variable changes from iteration to iteration only first value will be used and this may ruin your test so you might want to change it to vars.get('secretKey') expression
Also be aware that according to 9 Easy Solutions for a JMeter Load Test “Out of Memory” Failure article you should always be using the latest version of JMeter so consider upgrading to JMeter 5.4.1 (or whatever is the latest stable version available at JMeter Downloads page) on next available opportunity.
I have wrote an initialization script that sets user environment variables which are keys that have been hashed and encrypted...Once the keys have been created the key encryption exe is no longer required. I want to launch the main application and remove the init file containing the hashing and key encryption functions.
I am not having any trouble with any of the above...Everything works as should when independent of each other. The problem is that in order for the main application to have access to the newly created environment variables I need the init script to completely exit...
Everything I have tried, Popen with flags, os.system() and others have still left me in a situation where the parent process ends and the main application launches, however, the environment variables have not updated...I close and relaunch main.py and...boom the program sees the updated variables and all is fine.
All I want is the init script to run, spawn a new process that is not linked at all with init.py and then exit so it can be removed. I thought this would be simple but after many hours of head scratching and trying numerous things, I am still no closer.
If I have to I will simply bundle it as two separate .exe files but I wanted it to be a one click install type thing.
I am running windows 10 and this can be platform specific.
Links looked at:
How to stop/terminate a python script from running?
Using a Python subprocess call to invoke a Python script
Starting a separate process
https://docs.python.org/2/library/subprocess.html
Python: Howto launch a full process not a child process and retrieve the PID
And more...
Current closest result
p = Popen(["python","UserInterface.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE,
creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
Create an environment block, set the environment variable using SetEnvironmentVariable, and use CreateProcess to specify this environment block for the created process.
MSDN DOC:
To specify a different environment for a process, create a new
environment block and pass the pointer to it as a parameter to the
CreateProcess function.
...
To programmatically add or modify system environment variables, add
them to the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session
Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE
message with lParam set to the string "Environment". This allows
applications, such as the shell, to pick up your updates.
I'm trying to have data (generated by an application only after its launch) persisted across multiple invocations of an application, but only when they're started from the same shell session.
One possible way to do that would be to pass the data back from the application to the calling shell, but since environment variable changes are only passed from parent to child, I don't know how to implement that.
Practical example:
There is job command that create subdirectory with current datetime and does work inside. Sometimes job needs to be killed and restarted, so it need directory where if finished, like job --resume 21Fri_1849/data. I would like to save 21Jan_1849/data so I don't have to check and type it each time I need to resume job. If I created something like .last_job, and wanted to restart job in another session, it could resume wrong (last) job, so files are not solution (AFAIK).
How can this be done?
Since you're only trying to target Linux, there are a fair number of tricks available here. Consider this one:
#!/usr/bin/env bash
current_boot_id=$(</proc/sys/kernel/random/boot_id)
# honor myprog_shell_pid if set and valid, fall back to PPID otherwise
if [[ $myprog_shell_pid ]] && [[ -e /proc/$myprog_shell_pid/stat ]]; then
parent_pid=$myprog_shell_pid
else
parent_pid=$PPID
fi
parent_start_time=$(awk '{print $22}' "/proc/$parent_pid/stat")
mkdir -p "$HOME/.cache/myscript-sessions"
data=$HOME/.cache/myscript-sessions/${current_boot_id}:${parent_pid}:${parent_start_time}
Now, we have a data file name that changes:
When we're rebooted (because current_boot_id is updated)
If we're run from a different shell (because our PPID changes).
If we're run from a different shell with the same PID (because the start time for the parent PID will be different).
...and you can easily delete files with the wrong boot id (because the system rebooted), or with names that refer to PID/start-time combinations that don't exist.
One caveat is that by default, this is sensitive to being called by subshells (output=$(./yourprog) will have a different PPID than ./yourprog will), but if the parent shell runs export myprog_shell_pid=$$, that issue goes away.
You're crossing over to where you need a simple job management engine instead of just shell. Using 'make' and writing Makefiles is the probably the simplest way to set this up. You can write a rule that tells how to turn a stage 1 file into a stage 2 file based on file extension, and then make will know how far things got and how to resume next time you run it.
I need a way to constantly update a environment variable from a script. I need to use that environment variable in another program almost real time.
What I have is this code:
# !bin/bash
while :
do
AMA="$(cut -c 1-13 text.txt)"
source directory/this_script
done
I am getting the right information from my file when running cut this way. I just need to get this variable permanently updating if possible. Also a way to even get it to the environment.
Slackware Linux
After installation of Ruby Version Manager (RVM) as root on an Ubuntu 14.04. I am confronted with a strange behaviour of bash. Let's have a look at the exported environment variables. I login as user ubunutu and run exportin my bash. Here are three of rvm's exported environment variables, others are available:
declare -ax chpwd_functions='([0]="__rvm_cd_functions_set" [1]="__rvm_after_cd")'
declare -x rvm_version="1.25.28 (stable)"
declare -x rvm_ruby_mode
Everything is pretty fine, but when I run bash -c export we get only:
declare -x rvm_version="1.25.28 (stable)"
Can someone explain me why all empty environment variables and all arrays are removed in the child bash? What must I do to ensure that really all environment variables of a parent shell are available within a child shell?
This problem is really a blocker for me. I am using vagrant and its shell provisioner. In one script I setup rvm and in a second one I must configure some gemsets. The problem is that in the second script the rvm commands do not run. The active shell only gets those environment variables of rvm with are non-arrays and non-empty. Manually sourcing of rvm.sh is no solution!
It is because as per last line of man bash:
Array variables may not (yet) be exported.
I read somewhere a note by BASH developer that it is because exporting an array is very complex and error prone.
Also this line:
declare -x rvm_ruby_mode
is only declaring a name of the variable with export attribute set (without value), if you assign it a value it will be available in the sub shell.
Here is post by BASH author on export of array in BASH.
A variable is created when a value is assigned to a name using the = operator, for example
foo=bar
creates a variable named foo with the value bar.
declare is used for two reasons: one, to allow dynamic creation of variables (which is beyond the scope of this question), and two, to set attributes on names (not necessarily variables). The command
declare -x rvm_ruby_mode
simply sets the export attribute of the name rvm_ruby_mode. To actually create a variable whose name has the export attribute set, you need to use the = operator, just as without the declare command.
declare -x rvm_ruby_mode=
Now rvm_ruby_mode is an empty variable whose named is marked for export.
I say "marked for export" because variables are not exported until a subshell is created. Until then, there is simply a list of names that, if the name has a value when a subshell/child process is created, are copied into the new environment. This list is separate from the list of actual variables (which again are names with associated values).
As to why arrays cannot be exported? The environment is technically not a set of variables, since a variable is a shell construct and the environment is something used by all processes in POSIX, whether or not run by a shell. The environment is simply a list of strings of the form <name>=<value>. There is no standard for how to pack the elements of an array into a single string which any process can parse and reconstruct into an appropriate data structure. While it's possible that bash could make an exception if it new the child process was another bash shell and come up with some way of embedding an array in the environment (like it does with function definitions), apparently this has not been done.