“Variabilize” the ampersand (background a process)
Clash Royale CLAN TAG#URR8PPP
I want to know if there's a way to put the ampersand in a variable and still use it to send a process to the background.
This works:
BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
sleep 5 &
else
sleep 5
fi
But wouldn't it be cool to accomplish those five lines with only one? Like so:
BCKGRND='&'
sleep 5 $BCKGRND
But that doesn't work. If BCKGRND isn't set it works - but when it is set it's interpreted it as a literal '&' and errors out.
bash shell-script variable background-process
add a comment |
I want to know if there's a way to put the ampersand in a variable and still use it to send a process to the background.
This works:
BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
sleep 5 &
else
sleep 5
fi
But wouldn't it be cool to accomplish those five lines with only one? Like so:
BCKGRND='&'
sleep 5 $BCKGRND
But that doesn't work. If BCKGRND isn't set it works - but when it is set it's interpreted it as a literal '&' and errors out.
bash shell-script variable background-process
add a comment |
I want to know if there's a way to put the ampersand in a variable and still use it to send a process to the background.
This works:
BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
sleep 5 &
else
sleep 5
fi
But wouldn't it be cool to accomplish those five lines with only one? Like so:
BCKGRND='&'
sleep 5 $BCKGRND
But that doesn't work. If BCKGRND isn't set it works - but when it is set it's interpreted it as a literal '&' and errors out.
bash shell-script variable background-process
I want to know if there's a way to put the ampersand in a variable and still use it to send a process to the background.
This works:
BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
sleep 5 &
else
sleep 5
fi
But wouldn't it be cool to accomplish those five lines with only one? Like so:
BCKGRND='&'
sleep 5 $BCKGRND
But that doesn't work. If BCKGRND isn't set it works - but when it is set it's interpreted it as a literal '&' and errors out.
bash shell-script variable background-process
bash shell-script variable background-process
edited Jan 9 at 18:11
Stephen Kitt
168k24379457
168k24379457
asked Jan 9 at 14:13
BrowncoatOkieBrowncoatOkie
836
836
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
It's not possible to use a variable to background the call because variable expansion happens after the command-line is parsed for control operators (such as &&
and &
).
Yet another option would be to wrap the calls in a function:
mayberunbg()
if [ "$BCKGRND" = "yes" ]; then
"$@" &
else
"$@"
fi
... and then set the variable as needed:
$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+ Done "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+ Done "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$
What, noed
? +1 anyway, this is the cleanest solution.
– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
add a comment |
You can flip things and variabilise “foregrounding”:
FOREGROUND=fg
sleep 5 & $FOREGROUND
Set FOREGROUND
to true
or empty to run the process in the background. (Setting FOREGROUND
to true
to run in the background is admittedly confusing! Appropriate variable names are left as an exercise for the reader.)
4
that's nice but it won't work in a shell without job control (ie any script unlessset -m
was used).
– mosvy
Jan 9 at 15:47
add a comment |
You would probably have to use eval
:
eval "sleep 5" "$BCKGRND"
eval
causes the shell to re-evaluate the arguments given. A literal &
would therefore be interpreted as &
at the end of a command and not as an argument to the command, putting the command in the background.
2
A answer containingeval
should contain a warning, that this should be handles with care. See e.g. this answer.
– Ralf
Jan 9 at 14:30
I don't get what the problem is with"$BCKGRND"
evaluating to an empty argument.
– mosvy
Jan 9 at 14:48
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
@Kusalanandaeval
will join its arguments with spaces before doing the actual eval. Just try it:eval printf "'%sn'" foo "" "" ""
.eval foo "" "" "" ""
is completely similar toeval foo
, no matter whatIFS
or other thing is.
– mosvy
Jan 9 at 15:22
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.
– Barmar
Jan 10 at 1:40
|
show 4 more comments
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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%2funix.stackexchange.com%2fquestions%2f493464%2fvariabilize-the-ampersand-background-a-process%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
It's not possible to use a variable to background the call because variable expansion happens after the command-line is parsed for control operators (such as &&
and &
).
Yet another option would be to wrap the calls in a function:
mayberunbg()
if [ "$BCKGRND" = "yes" ]; then
"$@" &
else
"$@"
fi
... and then set the variable as needed:
$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+ Done "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+ Done "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$
What, noed
? +1 anyway, this is the cleanest solution.
– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
add a comment |
It's not possible to use a variable to background the call because variable expansion happens after the command-line is parsed for control operators (such as &&
and &
).
Yet another option would be to wrap the calls in a function:
mayberunbg()
if [ "$BCKGRND" = "yes" ]; then
"$@" &
else
"$@"
fi
... and then set the variable as needed:
$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+ Done "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+ Done "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$
What, noed
? +1 anyway, this is the cleanest solution.
– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
add a comment |
It's not possible to use a variable to background the call because variable expansion happens after the command-line is parsed for control operators (such as &&
and &
).
Yet another option would be to wrap the calls in a function:
mayberunbg()
if [ "$BCKGRND" = "yes" ]; then
"$@" &
else
"$@"
fi
... and then set the variable as needed:
$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+ Done "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+ Done "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$
It's not possible to use a variable to background the call because variable expansion happens after the command-line is parsed for control operators (such as &&
and &
).
Yet another option would be to wrap the calls in a function:
mayberunbg()
if [ "$BCKGRND" = "yes" ]; then
"$@" &
else
"$@"
fi
... and then set the variable as needed:
$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+ Done "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+ Done "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$
answered Jan 9 at 14:43
Jeff SchallerJeff Schaller
39.9k1054126
39.9k1054126
What, noed
? +1 anyway, this is the cleanest solution.
– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
add a comment |
What, noed
? +1 anyway, this is the cleanest solution.
– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
What, no
ed
? +1 anyway, this is the cleanest solution.– Stephen Kitt
Jan 9 at 14:46
What, no
ed
? +1 anyway, this is the cleanest solution.– Stephen Kitt
Jan 9 at 14:46
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
LOL @StephenKitt; now the gears are turning
– Jeff Schaller
Jan 9 at 14:47
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
I liked the eval answer for its simplicity but my actual real-world command I wanted to background was far too complicated with too many variables in it to be comfortable using eval. @jeff-schaller gave the answer that pointed me in the direction I went. Instead of a function, though, I put the entire command in a variable then used his if statement style to execute the command with or without the &.
– BrowncoatOkie
Jan 9 at 17:31
add a comment |
You can flip things and variabilise “foregrounding”:
FOREGROUND=fg
sleep 5 & $FOREGROUND
Set FOREGROUND
to true
or empty to run the process in the background. (Setting FOREGROUND
to true
to run in the background is admittedly confusing! Appropriate variable names are left as an exercise for the reader.)
4
that's nice but it won't work in a shell without job control (ie any script unlessset -m
was used).
– mosvy
Jan 9 at 15:47
add a comment |
You can flip things and variabilise “foregrounding”:
FOREGROUND=fg
sleep 5 & $FOREGROUND
Set FOREGROUND
to true
or empty to run the process in the background. (Setting FOREGROUND
to true
to run in the background is admittedly confusing! Appropriate variable names are left as an exercise for the reader.)
4
that's nice but it won't work in a shell without job control (ie any script unlessset -m
was used).
– mosvy
Jan 9 at 15:47
add a comment |
You can flip things and variabilise “foregrounding”:
FOREGROUND=fg
sleep 5 & $FOREGROUND
Set FOREGROUND
to true
or empty to run the process in the background. (Setting FOREGROUND
to true
to run in the background is admittedly confusing! Appropriate variable names are left as an exercise for the reader.)
You can flip things and variabilise “foregrounding”:
FOREGROUND=fg
sleep 5 & $FOREGROUND
Set FOREGROUND
to true
or empty to run the process in the background. (Setting FOREGROUND
to true
to run in the background is admittedly confusing! Appropriate variable names are left as an exercise for the reader.)
answered Jan 9 at 14:22
Stephen KittStephen Kitt
168k24379457
168k24379457
4
that's nice but it won't work in a shell without job control (ie any script unlessset -m
was used).
– mosvy
Jan 9 at 15:47
add a comment |
4
that's nice but it won't work in a shell without job control (ie any script unlessset -m
was used).
– mosvy
Jan 9 at 15:47
4
4
that's nice but it won't work in a shell without job control (ie any script unless
set -m
was used).– mosvy
Jan 9 at 15:47
that's nice but it won't work in a shell without job control (ie any script unless
set -m
was used).– mosvy
Jan 9 at 15:47
add a comment |
You would probably have to use eval
:
eval "sleep 5" "$BCKGRND"
eval
causes the shell to re-evaluate the arguments given. A literal &
would therefore be interpreted as &
at the end of a command and not as an argument to the command, putting the command in the background.
2
A answer containingeval
should contain a warning, that this should be handles with care. See e.g. this answer.
– Ralf
Jan 9 at 14:30
I don't get what the problem is with"$BCKGRND"
evaluating to an empty argument.
– mosvy
Jan 9 at 14:48
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
@Kusalanandaeval
will join its arguments with spaces before doing the actual eval. Just try it:eval printf "'%sn'" foo "" "" ""
.eval foo "" "" "" ""
is completely similar toeval foo
, no matter whatIFS
or other thing is.
– mosvy
Jan 9 at 15:22
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.
– Barmar
Jan 10 at 1:40
|
show 4 more comments
You would probably have to use eval
:
eval "sleep 5" "$BCKGRND"
eval
causes the shell to re-evaluate the arguments given. A literal &
would therefore be interpreted as &
at the end of a command and not as an argument to the command, putting the command in the background.
2
A answer containingeval
should contain a warning, that this should be handles with care. See e.g. this answer.
– Ralf
Jan 9 at 14:30
I don't get what the problem is with"$BCKGRND"
evaluating to an empty argument.
– mosvy
Jan 9 at 14:48
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
@Kusalanandaeval
will join its arguments with spaces before doing the actual eval. Just try it:eval printf "'%sn'" foo "" "" ""
.eval foo "" "" "" ""
is completely similar toeval foo
, no matter whatIFS
or other thing is.
– mosvy
Jan 9 at 15:22
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.
– Barmar
Jan 10 at 1:40
|
show 4 more comments
You would probably have to use eval
:
eval "sleep 5" "$BCKGRND"
eval
causes the shell to re-evaluate the arguments given. A literal &
would therefore be interpreted as &
at the end of a command and not as an argument to the command, putting the command in the background.
You would probably have to use eval
:
eval "sleep 5" "$BCKGRND"
eval
causes the shell to re-evaluate the arguments given. A literal &
would therefore be interpreted as &
at the end of a command and not as an argument to the command, putting the command in the background.
edited Jan 9 at 15:32
answered Jan 9 at 14:22
KusalanandaKusalananda
126k16239393
126k16239393
2
A answer containingeval
should contain a warning, that this should be handles with care. See e.g. this answer.
– Ralf
Jan 9 at 14:30
I don't get what the problem is with"$BCKGRND"
evaluating to an empty argument.
– mosvy
Jan 9 at 14:48
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
@Kusalanandaeval
will join its arguments with spaces before doing the actual eval. Just try it:eval printf "'%sn'" foo "" "" ""
.eval foo "" "" "" ""
is completely similar toeval foo
, no matter whatIFS
or other thing is.
– mosvy
Jan 9 at 15:22
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.
– Barmar
Jan 10 at 1:40
|
show 4 more comments
2
A answer containingeval
should contain a warning, that this should be handles with care. See e.g. this answer.
– Ralf
Jan 9 at 14:30
I don't get what the problem is with"$BCKGRND"
evaluating to an empty argument.
– mosvy
Jan 9 at 14:48
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
@Kusalanandaeval
will join its arguments with spaces before doing the actual eval. Just try it:eval printf "'%sn'" foo "" "" ""
.eval foo "" "" "" ""
is completely similar toeval foo
, no matter whatIFS
or other thing is.
– mosvy
Jan 9 at 15:22
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.
– Barmar
Jan 10 at 1:40
2
2
A answer containing
eval
should contain a warning, that this should be handles with care. See e.g. this answer.– Ralf
Jan 9 at 14:30
A answer containing
eval
should contain a warning, that this should be handles with care. See e.g. this answer.– Ralf
Jan 9 at 14:30
I don't get what the problem is with
"$BCKGRND"
evaluating to an empty argument.– mosvy
Jan 9 at 14:48
I don't get what the problem is with
"$BCKGRND"
evaluating to an empty argument.– mosvy
Jan 9 at 14:48
2
2
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
@Ralf absolutely irrelevant in this case. There's nothing special about eval -- you can execute commands via arithmetic expansions, for instance. Maybe there should be such a warning against using bash (or any similar shell) at all ;-)
– mosvy
Jan 9 at 14:54
1
1
@Kusalananda
eval
will join its arguments with spaces before doing the actual eval. Just try it: eval printf "'%sn'" foo "" "" ""
. eval foo "" "" "" ""
is completely similar to eval foo
, no matter what IFS
or other thing is.– mosvy
Jan 9 at 15:22
@Kusalananda
eval
will join its arguments with spaces before doing the actual eval. Just try it: eval printf "'%sn'" foo "" "" ""
. eval foo "" "" "" ""
is completely similar to eval foo
, no matter what IFS
or other thing is.– mosvy
Jan 9 at 15:22
1
1
The command being eval'ed should be in double quotes if it contains any special characters, e.g.
eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.– Barmar
Jan 10 at 1:40
The command being eval'ed should be in double quotes if it contains any special characters, e.g.
eval 'sleep $TIMEOUT' "$BACKGROUND"
. Otherwise you could get double expansions if the variable expands to another variable or contains special characters. Also, nested quoting can get tricky.– Barmar
Jan 10 at 1:40
|
show 4 more comments
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- 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%2funix.stackexchange.com%2fquestions%2f493464%2fvariabilize-the-ampersand-background-a-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