Get child process operation result from parent process
I know I can read parent's information in a child process by exporting a variable
myVariable=1
bash
echo $myVariable
exit
export myVariable=1
bash
echo $myVariable # 1
How can I access the variables defined in the child process from the parent?
bash
a=2
suspend
echo $a
bash process
add a comment |
I know I can read parent's information in a child process by exporting a variable
myVariable=1
bash
echo $myVariable
exit
export myVariable=1
bash
echo $myVariable # 1
How can I access the variables defined in the child process from the parent?
bash
a=2
suspend
echo $a
bash process
add a comment |
I know I can read parent's information in a child process by exporting a variable
myVariable=1
bash
echo $myVariable
exit
export myVariable=1
bash
echo $myVariable # 1
How can I access the variables defined in the child process from the parent?
bash
a=2
suspend
echo $a
bash process
I know I can read parent's information in a child process by exporting a variable
myVariable=1
bash
echo $myVariable
exit
export myVariable=1
bash
echo $myVariable # 1
How can I access the variables defined in the child process from the parent?
bash
a=2
suspend
echo $a
bash process
bash process
asked Feb 1 at 0:53
jedijedi
281113
281113
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You can't do this.
When you start a new shell, it's an unrelated process and the parent can't "look inside" it to see what it has in memory (this is a security boundary of sorts). Its variables are not shared and not published where someone else can see them.
It gets a copy of the existing environment variables, but any changes it makes to them are for itself alone, and its children. There's no "backwards" communication until the shell exits, and all there is at that point is a single exit code.
When you're doing this interactively as you've shown, that's the end of the story. Your best bet is to save data into a file, which you can then read from or source
back in to the parent. If you really can't use a file, I have an awful way of doing it right at the end, but I recommend rethinking what you're trying to achieve - it'd be nice to be able to make this work normally (and some other shells do have shared variables!), it's just not achievable here.
If you're making a program or shell script that runs non-interactively, some or all of source
, eval
, and printing out data to standard output may help you, as noted in an existing answer. If you exit the child shell, you can pass a single byte of information back in your exit code with exit 123
, which you can read with $?
in the parent.
If you really really need to migrate something out, here is a very nasty hack to achieve it interactively with no intermediate files:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%sn' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%sn' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
There are significant limitations here, particularly if you're not in control of the whole environment - a newline within an environment variable value could trick you into setting a value you didn't want, for example.
This works by exporting a
so that it appears in the environment of subprocesses and then launching one (sleep 60
here), in the background (&
), with the PID of sleep
printed out (echo $!
). When you suspend the inner shell, you can read the sleep
process's environment variables given by its parent from the outside - those are public in the /proc
filesystem - but they're separated by null bytes, so xargs -0
splits them up and printf '%sn'
outputs one per line. At that point there's a complete list of variables, and we can grep
out the one we want, optionally chopping out just the value after the =
with cut
and setting it. The sleep
will end on its own, which is what we see at the end of the transcript ([1]+ Done ...
).
You'd need to do it all again if you wanted to pick up on a change to a
in the child - and the child will never see a change that you make to a
in the parent: all we've done is make another copy. The reason for the sleep
process is that we can only see the inbound environment variables of a process, and not any of the shell's internal variable values even if they're exported.
I don't recommend doing this or relying on it, and I can't see any value in using it, but if you do end up in a situation where it's truly, vitally necessary then it should work.
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
add a comment |
From this question on Stack Overflow the solution is to use source
when executing the child process:
In a.sh
do source b.sh
instead of ./b.sh
a.sh
should look like this :
#!/bin/bash
export A=1
source b.sh
echo parent "$A"
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1114589%2fget-child-process-operation-result-from-parent-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can't do this.
When you start a new shell, it's an unrelated process and the parent can't "look inside" it to see what it has in memory (this is a security boundary of sorts). Its variables are not shared and not published where someone else can see them.
It gets a copy of the existing environment variables, but any changes it makes to them are for itself alone, and its children. There's no "backwards" communication until the shell exits, and all there is at that point is a single exit code.
When you're doing this interactively as you've shown, that's the end of the story. Your best bet is to save data into a file, which you can then read from or source
back in to the parent. If you really can't use a file, I have an awful way of doing it right at the end, but I recommend rethinking what you're trying to achieve - it'd be nice to be able to make this work normally (and some other shells do have shared variables!), it's just not achievable here.
If you're making a program or shell script that runs non-interactively, some or all of source
, eval
, and printing out data to standard output may help you, as noted in an existing answer. If you exit the child shell, you can pass a single byte of information back in your exit code with exit 123
, which you can read with $?
in the parent.
If you really really need to migrate something out, here is a very nasty hack to achieve it interactively with no intermediate files:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%sn' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%sn' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
There are significant limitations here, particularly if you're not in control of the whole environment - a newline within an environment variable value could trick you into setting a value you didn't want, for example.
This works by exporting a
so that it appears in the environment of subprocesses and then launching one (sleep 60
here), in the background (&
), with the PID of sleep
printed out (echo $!
). When you suspend the inner shell, you can read the sleep
process's environment variables given by its parent from the outside - those are public in the /proc
filesystem - but they're separated by null bytes, so xargs -0
splits them up and printf '%sn'
outputs one per line. At that point there's a complete list of variables, and we can grep
out the one we want, optionally chopping out just the value after the =
with cut
and setting it. The sleep
will end on its own, which is what we see at the end of the transcript ([1]+ Done ...
).
You'd need to do it all again if you wanted to pick up on a change to a
in the child - and the child will never see a change that you make to a
in the parent: all we've done is make another copy. The reason for the sleep
process is that we can only see the inbound environment variables of a process, and not any of the shell's internal variable values even if they're exported.
I don't recommend doing this or relying on it, and I can't see any value in using it, but if you do end up in a situation where it's truly, vitally necessary then it should work.
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
add a comment |
You can't do this.
When you start a new shell, it's an unrelated process and the parent can't "look inside" it to see what it has in memory (this is a security boundary of sorts). Its variables are not shared and not published where someone else can see them.
It gets a copy of the existing environment variables, but any changes it makes to them are for itself alone, and its children. There's no "backwards" communication until the shell exits, and all there is at that point is a single exit code.
When you're doing this interactively as you've shown, that's the end of the story. Your best bet is to save data into a file, which you can then read from or source
back in to the parent. If you really can't use a file, I have an awful way of doing it right at the end, but I recommend rethinking what you're trying to achieve - it'd be nice to be able to make this work normally (and some other shells do have shared variables!), it's just not achievable here.
If you're making a program or shell script that runs non-interactively, some or all of source
, eval
, and printing out data to standard output may help you, as noted in an existing answer. If you exit the child shell, you can pass a single byte of information back in your exit code with exit 123
, which you can read with $?
in the parent.
If you really really need to migrate something out, here is a very nasty hack to achieve it interactively with no intermediate files:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%sn' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%sn' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
There are significant limitations here, particularly if you're not in control of the whole environment - a newline within an environment variable value could trick you into setting a value you didn't want, for example.
This works by exporting a
so that it appears in the environment of subprocesses and then launching one (sleep 60
here), in the background (&
), with the PID of sleep
printed out (echo $!
). When you suspend the inner shell, you can read the sleep
process's environment variables given by its parent from the outside - those are public in the /proc
filesystem - but they're separated by null bytes, so xargs -0
splits them up and printf '%sn'
outputs one per line. At that point there's a complete list of variables, and we can grep
out the one we want, optionally chopping out just the value after the =
with cut
and setting it. The sleep
will end on its own, which is what we see at the end of the transcript ([1]+ Done ...
).
You'd need to do it all again if you wanted to pick up on a change to a
in the child - and the child will never see a change that you make to a
in the parent: all we've done is make another copy. The reason for the sleep
process is that we can only see the inbound environment variables of a process, and not any of the shell's internal variable values even if they're exported.
I don't recommend doing this or relying on it, and I can't see any value in using it, but if you do end up in a situation where it's truly, vitally necessary then it should work.
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
add a comment |
You can't do this.
When you start a new shell, it's an unrelated process and the parent can't "look inside" it to see what it has in memory (this is a security boundary of sorts). Its variables are not shared and not published where someone else can see them.
It gets a copy of the existing environment variables, but any changes it makes to them are for itself alone, and its children. There's no "backwards" communication until the shell exits, and all there is at that point is a single exit code.
When you're doing this interactively as you've shown, that's the end of the story. Your best bet is to save data into a file, which you can then read from or source
back in to the parent. If you really can't use a file, I have an awful way of doing it right at the end, but I recommend rethinking what you're trying to achieve - it'd be nice to be able to make this work normally (and some other shells do have shared variables!), it's just not achievable here.
If you're making a program or shell script that runs non-interactively, some or all of source
, eval
, and printing out data to standard output may help you, as noted in an existing answer. If you exit the child shell, you can pass a single byte of information back in your exit code with exit 123
, which you can read with $?
in the parent.
If you really really need to migrate something out, here is a very nasty hack to achieve it interactively with no intermediate files:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%sn' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%sn' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
There are significant limitations here, particularly if you're not in control of the whole environment - a newline within an environment variable value could trick you into setting a value you didn't want, for example.
This works by exporting a
so that it appears in the environment of subprocesses and then launching one (sleep 60
here), in the background (&
), with the PID of sleep
printed out (echo $!
). When you suspend the inner shell, you can read the sleep
process's environment variables given by its parent from the outside - those are public in the /proc
filesystem - but they're separated by null bytes, so xargs -0
splits them up and printf '%sn'
outputs one per line. At that point there's a complete list of variables, and we can grep
out the one we want, optionally chopping out just the value after the =
with cut
and setting it. The sleep
will end on its own, which is what we see at the end of the transcript ([1]+ Done ...
).
You'd need to do it all again if you wanted to pick up on a change to a
in the child - and the child will never see a change that you make to a
in the parent: all we've done is make another copy. The reason for the sleep
process is that we can only see the inbound environment variables of a process, and not any of the shell's internal variable values even if they're exported.
I don't recommend doing this or relying on it, and I can't see any value in using it, but if you do end up in a situation where it's truly, vitally necessary then it should work.
You can't do this.
When you start a new shell, it's an unrelated process and the parent can't "look inside" it to see what it has in memory (this is a security boundary of sorts). Its variables are not shared and not published where someone else can see them.
It gets a copy of the existing environment variables, but any changes it makes to them are for itself alone, and its children. There's no "backwards" communication until the shell exits, and all there is at that point is a single exit code.
When you're doing this interactively as you've shown, that's the end of the story. Your best bet is to save data into a file, which you can then read from or source
back in to the parent. If you really can't use a file, I have an awful way of doing it right at the end, but I recommend rethinking what you're trying to achieve - it'd be nice to be able to make this work normally (and some other shells do have shared variables!), it's just not achievable here.
If you're making a program or shell script that runs non-interactively, some or all of source
, eval
, and printing out data to standard output may help you, as noted in an existing answer. If you exit the child shell, you can pass a single byte of information back in your exit code with exit 123
, which you can read with $?
in the parent.
If you really really need to migrate something out, here is a very nasty hack to achieve it interactively with no intermediate files:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%sn' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%sn' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
There are significant limitations here, particularly if you're not in control of the whole environment - a newline within an environment variable value could trick you into setting a value you didn't want, for example.
This works by exporting a
so that it appears in the environment of subprocesses and then launching one (sleep 60
here), in the background (&
), with the PID of sleep
printed out (echo $!
). When you suspend the inner shell, you can read the sleep
process's environment variables given by its parent from the outside - those are public in the /proc
filesystem - but they're separated by null bytes, so xargs -0
splits them up and printf '%sn'
outputs one per line. At that point there's a complete list of variables, and we can grep
out the one we want, optionally chopping out just the value after the =
with cut
and setting it. The sleep
will end on its own, which is what we see at the end of the transcript ([1]+ Done ...
).
You'd need to do it all again if you wanted to pick up on a change to a
in the child - and the child will never see a change that you make to a
in the parent: all we've done is make another copy. The reason for the sleep
process is that we can only see the inbound environment variables of a process, and not any of the shell's internal variable values even if they're exported.
I don't recommend doing this or relying on it, and I can't see any value in using it, but if you do end up in a situation where it's truly, vitally necessary then it should work.
answered Feb 1 at 5:21
Michael HomerMichael Homer
1575
1575
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
add a comment |
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
This is a terrific answer! I asked myself this question while making an exrcise so no real world scenario to achieve what I was asking for. I wanted to know this just for an exercise and for my personal interest. If I had to, I would definitely use your recommended way, no nasty hacks ;) But thanks for the hack anyway ;) Thank you for rationale and a substantive and educational response. I give you +1. Thank you!
– jedi
Feb 1 at 9:48
add a comment |
From this question on Stack Overflow the solution is to use source
when executing the child process:
In a.sh
do source b.sh
instead of ./b.sh
a.sh
should look like this :
#!/bin/bash
export A=1
source b.sh
echo parent "$A"
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
add a comment |
From this question on Stack Overflow the solution is to use source
when executing the child process:
In a.sh
do source b.sh
instead of ./b.sh
a.sh
should look like this :
#!/bin/bash
export A=1
source b.sh
echo parent "$A"
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
add a comment |
From this question on Stack Overflow the solution is to use source
when executing the child process:
In a.sh
do source b.sh
instead of ./b.sh
a.sh
should look like this :
#!/bin/bash
export A=1
source b.sh
echo parent "$A"
From this question on Stack Overflow the solution is to use source
when executing the child process:
In a.sh
do source b.sh
instead of ./b.sh
a.sh
should look like this :
#!/bin/bash
export A=1
source b.sh
echo parent "$A"
answered Feb 1 at 1:52
Kristopher IvesKristopher Ives
2,94211525
2,94211525
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
add a comment |
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
Is it possible to achieve what I want without having to create files? Just in the terminal.
– jedi
Feb 1 at 1:58
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
See unix.stackexchange.com/questions/420990/…
– Kristopher Ives
Feb 1 at 2:09
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1114589%2fget-child-process-operation-result-from-parent-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown