What is the difference between running a command directly and with `bash -c`? The Next CEO of Stack OverflowDoes the shebang determine the shell which runs the script?What exactly happens when I execute a file in my shell?Difference between sh -x and ./ for script executionThe first Line of Scriptingcomm fails on bash variable inputbash -c and noninteractive shellWhat is the language that appears on the first line of a script?Is the shell created by `bash -i -c <command>` interactive?How to specify a compound command as an argument to another command?Use system command instead of Bash builtin without specifying the full pathWhat is the difference between kill , pkill and killallCompare running a command directly and in backgroundWhat differences are between running a command in shell with and without `bash -c`?Differences between reserved word and command `time` on shell builtin, function, pipeline and command list?Why does Bash implement time as a reserved word instead of a builtin?What is the difference between using bash and sh to run a script?How does the shell decide which of same-name keyword, builtin, and external command to run?What's the difference between using shell command (e.g. foo) directly and using $(foo)?Difference between “cd -” and “cd ~-”
How can the PCs determine if an item is a phylactery?
Small nick on power cord from an electric alarm clock, and copper wiring exposed but intact
Could you use a laser beam as a modulated carrier wave for radio signal?
Compensation for working overtime on Saturdays
Traveling with my 5 year old daughter (as the father) without the mother from Germany to Mexico
What are the unusually-enlarged wing sections on this P-38 Lightning?
Find the majority element, which appears more than half the time
Strange use of "whether ... than ..." in official text
Can this transistor (2n2222) take 6V on emitter-base? Am I reading datasheet incorrectly?
pgfplots: How to draw a tangent graph below two others?
How do I keep Mac Emacs from trapping M-`?
How should I connect my cat5 cable to connectors having an orange-green line?
Car headlights in a world without electricity
Another proof that dividing by 0 does not exist -- is it right?
Raspberry pi 3 B with Ubuntu 18.04 server arm64: what pi version
Find a path from s to t using as few red nodes as possible
Mathematica command that allows it to read my intentions
How does a dynamic QR code work?
What did the word "leisure" mean in late 18th Century usage?
Why can't we say "I have been having a dog"?
Why do we say “un seul M” and not “une seule M” even though M is a “consonne”?
Could a dragon use its wings to swim?
Does Germany produce more waste than the US?
Direct Implications Between USA and UK in Event of No-Deal Brexit
What is the difference between running a command directly and with `bash -c`?
The Next CEO of Stack OverflowDoes the shebang determine the shell which runs the script?What exactly happens when I execute a file in my shell?Difference between sh -x and ./ for script executionThe first Line of Scriptingcomm fails on bash variable inputbash -c and noninteractive shellWhat is the language that appears on the first line of a script?Is the shell created by `bash -i -c <command>` interactive?How to specify a compound command as an argument to another command?Use system command instead of Bash builtin without specifying the full pathWhat is the difference between kill , pkill and killallCompare running a command directly and in backgroundWhat differences are between running a command in shell with and without `bash -c`?Differences between reserved word and command `time` on shell builtin, function, pipeline and command list?Why does Bash implement time as a reserved word instead of a builtin?What is the difference between using bash and sh to run a script?How does the shell decide which of same-name keyword, builtin, and external command to run?What's the difference between using shell command (e.g. foo) directly and using $(foo)?Difference between “cd -” and “cd ~-”
For a command (builtin or external), what is the difference of
running it directly in a bash shell process and with bash -c in
the bash shell? What are their advantages and disadvantages
comparing to each other?
For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.
bash
add a comment |
For a command (builtin or external), what is the difference of
running it directly in a bash shell process and with bash -c in
the bash shell? What are their advantages and disadvantages
comparing to each other?
For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.
bash
add a comment |
For a command (builtin or external), what is the difference of
running it directly in a bash shell process and with bash -c in
the bash shell? What are their advantages and disadvantages
comparing to each other?
For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.
bash
For a command (builtin or external), what is the difference of
running it directly in a bash shell process and with bash -c in
the bash shell? What are their advantages and disadvantages
comparing to each other?
For example, in a bash shell, run `date` directly, and run `bash -c
date`. Also consider a builtin command instead of an external one.
bash
bash
edited Apr 14 '16 at 23:38
Tim
asked Apr 14 '16 at 23:12
TimTim
28.4k78269490
28.4k78269490
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
The
-coption allows programs to run commands.
It’s a lot easier to fork and doexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);than it is to fork, create a pipe, fork again,
callexeclin each child, callwait, check the exit status,
fork again, callclose(1), open the file,
ensure that it is open on file descriptor 1, and do anotherexecl.
I believe that this was the reason why the option was created
in the first place.The
system()library function runs a command by the above method.- It provides a way to take an arbitrarily complex command
and make it look like a simple command.
This is useful with programs that run a user-specified command,
such asfind … -execorxargs.
But you already knew that; it was part of the answer to your question,
How to specify a compound command as an argument to another command? It can come in handy
if you’re running an interactive shell other than bash.
Conversely, if you are running bash, you can use this syntax$ ash -c "command"
︙
$ csh -c "command"
︙
$ dash -c "command"
︙
$ zsh -c "command"
︙to run one command in another shell,
as all of those shells also recognize the-coption.
Of course you could achieve the same result with$ ash
ash$ command
︙
ash$ exit
$ csh
csh$ command
︙
csh$ exit
$ dash
dash$ command
︙
dash$ exit
$ zsh
zsh$ command
︙
zsh$ exitI used
ash$, etc., to illustrate the prompts from the different shells;
you probably wouldn’t actually get those.It can come in handy
if you want to run one command in a “fresh” bash shell; for example,$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2or
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtinThe above is a misleading over-simplification.
When bash is run with-c, it is considered a non-interactive shell,
and it does not read~/.bashrc, unless is-ispecified. So,$ type cp
cp is aliased to ‘cp -i’ # Defined in ~/.bashrc
$ cp .file1 file2
cp: overwrite ‘file2’? n
$ bash -c "cp .file1 file2"
# Existing file is overwritten without confirmation!
$ bash -c -i "cp .file1 file2"
cp: overwrite ‘file2’? nYou could use
-ci,-i -cor-icinstead of-c -i.This probably applies to some extent to the other shells
mentioned in paragraph 3, so the long form (i.e., the second form,
which is actually exactly the same amount of typing) might be safer, especially if you have initialization/configuration files
set up for those shells.As Wildcard explained, since you’re running a new process tree
(a new shell process and, potentially, its child process(es)),
changes to the environment made in the subshell
cannot affect the parent shell (current directory,
values of environment variables, function definitions, etc.)
Therefore, it’s hard to imagine a shell builtin command
that would be useful when run bysh -c.fg,bg, andjobscannot affect or access background jobs
started by the parent shell, nor canwaitwait for them.sh -c "exec some_program"is essentially equivalent
to just runningsome_programthe normal way,
directly from the interactive shell.sh -c exitis a big waste of time.ulimitandumaskcould change the system settings
for the child process, and then exit without exercising them.Just about the only builtin command that would be functional
in ash -ccontext iskill.
Of course, the commands that only produce output
(echo,printf,pwdandtype) are unaffected,
and, if you write a file, that will persist.- Of course you can use a builtin in conjunction with
an external command; e.g.,sh -c "cd some_directory; some_program"
but you can achieve essentially the same effect with a normal subshell:(cd some_directory; some_program)
which is more efficient.
The same (both parts) can be said for something likesh -c "umask 77; some_program"
orulimit(orshopt).
And since you can put an arbitrarily complex command after-c—
up to the complexity of a full-blown shell script —
you might have occasion to use any of the repertoire of builtins;
e.g.,source,read,export,times,setandunset, etc.
+1 except I think you go too far on builtins. To be clearecho printf type pwdare builtins; so areset shopt shift read readarray mapfile trap declare/typeset export local let readonly unsetwhich don't affect the parent but may still be useful inside a moderately complicated-c.
– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example ofsh -cbeing used with a complex command line including three programs, a pipe, a&&, and a redirection; I showed an example of it being used with a compound command line including acd, a;, and a program; I showed an example of it being used withexec; and I said it could be used with builtins likeecho,kill,printf,pwdandtype(and alsoexit,ulimit, andumask). What more do you want to know? … (Cont’d)
– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it meanexecve()can operate on a script?”, (1) that has nothing to do withbash -c, and (2) what research have you done? Theexecveman page answers this, and a search of this site yields this, this, this, this, this, and this.
– G-Man
Apr 15 '16 at 22:45
add a comment |
Running bash -c "my command here" vs. just running my command here is primarily different in that the former starts a subshell and the latter runs the commands in the current shell.
As far as built-in commands vs. external commands, it doesn't really relate—anything you can run in the current shell, you can run in a subshell.
There are a number of differences in the effects, however:
- Changes to the environment made in the subshell cannot affect the parent shell (current directory, values of environment variables, function definitions, etc.)
- Variables set in the parent shell that have not been exported will be unavailable in the subshell.
This is far from an exhaustive list of differences, but it contains the key point: you are running a different process with bash -c; it's not the same process as your original shell.
There is also a performance hit incurred by spawning a subshell; this is most relevant if your script is run frequently, or if your command is inside a loop of some kind.
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
add a comment |
The -c option basically runs a mini-shell script provided as a CLI argument rather than a file.
$ bash -c the_script the_scriptname 1 2 3
is virtually equivalent to:
$ echo the_script > the_scriptname
$ bash the_scriptname 1 2 3
$ rm the_scriptname
As you can see from:
$ bash -c 'printf " ->%sn" $0 "$@"; echo $-;' scriptname 1 2 3
->scriptname
->1
->2
->3
hBc
(In English:
$0 == scriptname; $@ == (1 2 3);
and bash will:
hash commands; perform Brace expansion, and it has been run with the -c flag)
and:
$ echo 'printf " ->%sn" $0 "$@"; echo $-;' > scriptname
$ bash scriptname 1 2 3
->scriptname
->1
->2
->3
hB
add a comment |
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to
the positional parameters, starting with $0.
This will solve your questions I guess
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
add a comment |
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%2f276581%2fwhat-is-the-difference-between-running-a-command-directly-and-with-bash-c%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
The
-coption allows programs to run commands.
It’s a lot easier to fork and doexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);than it is to fork, create a pipe, fork again,
callexeclin each child, callwait, check the exit status,
fork again, callclose(1), open the file,
ensure that it is open on file descriptor 1, and do anotherexecl.
I believe that this was the reason why the option was created
in the first place.The
system()library function runs a command by the above method.- It provides a way to take an arbitrarily complex command
and make it look like a simple command.
This is useful with programs that run a user-specified command,
such asfind … -execorxargs.
But you already knew that; it was part of the answer to your question,
How to specify a compound command as an argument to another command? It can come in handy
if you’re running an interactive shell other than bash.
Conversely, if you are running bash, you can use this syntax$ ash -c "command"
︙
$ csh -c "command"
︙
$ dash -c "command"
︙
$ zsh -c "command"
︙to run one command in another shell,
as all of those shells also recognize the-coption.
Of course you could achieve the same result with$ ash
ash$ command
︙
ash$ exit
$ csh
csh$ command
︙
csh$ exit
$ dash
dash$ command
︙
dash$ exit
$ zsh
zsh$ command
︙
zsh$ exitI used
ash$, etc., to illustrate the prompts from the different shells;
you probably wouldn’t actually get those.It can come in handy
if you want to run one command in a “fresh” bash shell; for example,$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2or
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtinThe above is a misleading over-simplification.
When bash is run with-c, it is considered a non-interactive shell,
and it does not read~/.bashrc, unless is-ispecified. So,$ type cp
cp is aliased to ‘cp -i’ # Defined in ~/.bashrc
$ cp .file1 file2
cp: overwrite ‘file2’? n
$ bash -c "cp .file1 file2"
# Existing file is overwritten without confirmation!
$ bash -c -i "cp .file1 file2"
cp: overwrite ‘file2’? nYou could use
-ci,-i -cor-icinstead of-c -i.This probably applies to some extent to the other shells
mentioned in paragraph 3, so the long form (i.e., the second form,
which is actually exactly the same amount of typing) might be safer, especially if you have initialization/configuration files
set up for those shells.As Wildcard explained, since you’re running a new process tree
(a new shell process and, potentially, its child process(es)),
changes to the environment made in the subshell
cannot affect the parent shell (current directory,
values of environment variables, function definitions, etc.)
Therefore, it’s hard to imagine a shell builtin command
that would be useful when run bysh -c.fg,bg, andjobscannot affect or access background jobs
started by the parent shell, nor canwaitwait for them.sh -c "exec some_program"is essentially equivalent
to just runningsome_programthe normal way,
directly from the interactive shell.sh -c exitis a big waste of time.ulimitandumaskcould change the system settings
for the child process, and then exit without exercising them.Just about the only builtin command that would be functional
in ash -ccontext iskill.
Of course, the commands that only produce output
(echo,printf,pwdandtype) are unaffected,
and, if you write a file, that will persist.- Of course you can use a builtin in conjunction with
an external command; e.g.,sh -c "cd some_directory; some_program"
but you can achieve essentially the same effect with a normal subshell:(cd some_directory; some_program)
which is more efficient.
The same (both parts) can be said for something likesh -c "umask 77; some_program"
orulimit(orshopt).
And since you can put an arbitrarily complex command after-c—
up to the complexity of a full-blown shell script —
you might have occasion to use any of the repertoire of builtins;
e.g.,source,read,export,times,setandunset, etc.
+1 except I think you go too far on builtins. To be clearecho printf type pwdare builtins; so areset shopt shift read readarray mapfile trap declare/typeset export local let readonly unsetwhich don't affect the parent but may still be useful inside a moderately complicated-c.
– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example ofsh -cbeing used with a complex command line including three programs, a pipe, a&&, and a redirection; I showed an example of it being used with a compound command line including acd, a;, and a program; I showed an example of it being used withexec; and I said it could be used with builtins likeecho,kill,printf,pwdandtype(and alsoexit,ulimit, andumask). What more do you want to know? … (Cont’d)
– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it meanexecve()can operate on a script?”, (1) that has nothing to do withbash -c, and (2) what research have you done? Theexecveman page answers this, and a search of this site yields this, this, this, this, this, and this.
– G-Man
Apr 15 '16 at 22:45
add a comment |
The
-coption allows programs to run commands.
It’s a lot easier to fork and doexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);than it is to fork, create a pipe, fork again,
callexeclin each child, callwait, check the exit status,
fork again, callclose(1), open the file,
ensure that it is open on file descriptor 1, and do anotherexecl.
I believe that this was the reason why the option was created
in the first place.The
system()library function runs a command by the above method.- It provides a way to take an arbitrarily complex command
and make it look like a simple command.
This is useful with programs that run a user-specified command,
such asfind … -execorxargs.
But you already knew that; it was part of the answer to your question,
How to specify a compound command as an argument to another command? It can come in handy
if you’re running an interactive shell other than bash.
Conversely, if you are running bash, you can use this syntax$ ash -c "command"
︙
$ csh -c "command"
︙
$ dash -c "command"
︙
$ zsh -c "command"
︙to run one command in another shell,
as all of those shells also recognize the-coption.
Of course you could achieve the same result with$ ash
ash$ command
︙
ash$ exit
$ csh
csh$ command
︙
csh$ exit
$ dash
dash$ command
︙
dash$ exit
$ zsh
zsh$ command
︙
zsh$ exitI used
ash$, etc., to illustrate the prompts from the different shells;
you probably wouldn’t actually get those.It can come in handy
if you want to run one command in a “fresh” bash shell; for example,$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2or
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtinThe above is a misleading over-simplification.
When bash is run with-c, it is considered a non-interactive shell,
and it does not read~/.bashrc, unless is-ispecified. So,$ type cp
cp is aliased to ‘cp -i’ # Defined in ~/.bashrc
$ cp .file1 file2
cp: overwrite ‘file2’? n
$ bash -c "cp .file1 file2"
# Existing file is overwritten without confirmation!
$ bash -c -i "cp .file1 file2"
cp: overwrite ‘file2’? nYou could use
-ci,-i -cor-icinstead of-c -i.This probably applies to some extent to the other shells
mentioned in paragraph 3, so the long form (i.e., the second form,
which is actually exactly the same amount of typing) might be safer, especially if you have initialization/configuration files
set up for those shells.As Wildcard explained, since you’re running a new process tree
(a new shell process and, potentially, its child process(es)),
changes to the environment made in the subshell
cannot affect the parent shell (current directory,
values of environment variables, function definitions, etc.)
Therefore, it’s hard to imagine a shell builtin command
that would be useful when run bysh -c.fg,bg, andjobscannot affect or access background jobs
started by the parent shell, nor canwaitwait for them.sh -c "exec some_program"is essentially equivalent
to just runningsome_programthe normal way,
directly from the interactive shell.sh -c exitis a big waste of time.ulimitandumaskcould change the system settings
for the child process, and then exit without exercising them.Just about the only builtin command that would be functional
in ash -ccontext iskill.
Of course, the commands that only produce output
(echo,printf,pwdandtype) are unaffected,
and, if you write a file, that will persist.- Of course you can use a builtin in conjunction with
an external command; e.g.,sh -c "cd some_directory; some_program"
but you can achieve essentially the same effect with a normal subshell:(cd some_directory; some_program)
which is more efficient.
The same (both parts) can be said for something likesh -c "umask 77; some_program"
orulimit(orshopt).
And since you can put an arbitrarily complex command after-c—
up to the complexity of a full-blown shell script —
you might have occasion to use any of the repertoire of builtins;
e.g.,source,read,export,times,setandunset, etc.
+1 except I think you go too far on builtins. To be clearecho printf type pwdare builtins; so areset shopt shift read readarray mapfile trap declare/typeset export local let readonly unsetwhich don't affect the parent but may still be useful inside a moderately complicated-c.
– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example ofsh -cbeing used with a complex command line including three programs, a pipe, a&&, and a redirection; I showed an example of it being used with a compound command line including acd, a;, and a program; I showed an example of it being used withexec; and I said it could be used with builtins likeecho,kill,printf,pwdandtype(and alsoexit,ulimit, andumask). What more do you want to know? … (Cont’d)
– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it meanexecve()can operate on a script?”, (1) that has nothing to do withbash -c, and (2) what research have you done? Theexecveman page answers this, and a search of this site yields this, this, this, this, this, and this.
– G-Man
Apr 15 '16 at 22:45
add a comment |
The
-coption allows programs to run commands.
It’s a lot easier to fork and doexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);than it is to fork, create a pipe, fork again,
callexeclin each child, callwait, check the exit status,
fork again, callclose(1), open the file,
ensure that it is open on file descriptor 1, and do anotherexecl.
I believe that this was the reason why the option was created
in the first place.The
system()library function runs a command by the above method.- It provides a way to take an arbitrarily complex command
and make it look like a simple command.
This is useful with programs that run a user-specified command,
such asfind … -execorxargs.
But you already knew that; it was part of the answer to your question,
How to specify a compound command as an argument to another command? It can come in handy
if you’re running an interactive shell other than bash.
Conversely, if you are running bash, you can use this syntax$ ash -c "command"
︙
$ csh -c "command"
︙
$ dash -c "command"
︙
$ zsh -c "command"
︙to run one command in another shell,
as all of those shells also recognize the-coption.
Of course you could achieve the same result with$ ash
ash$ command
︙
ash$ exit
$ csh
csh$ command
︙
csh$ exit
$ dash
dash$ command
︙
dash$ exit
$ zsh
zsh$ command
︙
zsh$ exitI used
ash$, etc., to illustrate the prompts from the different shells;
you probably wouldn’t actually get those.It can come in handy
if you want to run one command in a “fresh” bash shell; for example,$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2or
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtinThe above is a misleading over-simplification.
When bash is run with-c, it is considered a non-interactive shell,
and it does not read~/.bashrc, unless is-ispecified. So,$ type cp
cp is aliased to ‘cp -i’ # Defined in ~/.bashrc
$ cp .file1 file2
cp: overwrite ‘file2’? n
$ bash -c "cp .file1 file2"
# Existing file is overwritten without confirmation!
$ bash -c -i "cp .file1 file2"
cp: overwrite ‘file2’? nYou could use
-ci,-i -cor-icinstead of-c -i.This probably applies to some extent to the other shells
mentioned in paragraph 3, so the long form (i.e., the second form,
which is actually exactly the same amount of typing) might be safer, especially if you have initialization/configuration files
set up for those shells.As Wildcard explained, since you’re running a new process tree
(a new shell process and, potentially, its child process(es)),
changes to the environment made in the subshell
cannot affect the parent shell (current directory,
values of environment variables, function definitions, etc.)
Therefore, it’s hard to imagine a shell builtin command
that would be useful when run bysh -c.fg,bg, andjobscannot affect or access background jobs
started by the parent shell, nor canwaitwait for them.sh -c "exec some_program"is essentially equivalent
to just runningsome_programthe normal way,
directly from the interactive shell.sh -c exitis a big waste of time.ulimitandumaskcould change the system settings
for the child process, and then exit without exercising them.Just about the only builtin command that would be functional
in ash -ccontext iskill.
Of course, the commands that only produce output
(echo,printf,pwdandtype) are unaffected,
and, if you write a file, that will persist.- Of course you can use a builtin in conjunction with
an external command; e.g.,sh -c "cd some_directory; some_program"
but you can achieve essentially the same effect with a normal subshell:(cd some_directory; some_program)
which is more efficient.
The same (both parts) can be said for something likesh -c "umask 77; some_program"
orulimit(orshopt).
And since you can put an arbitrarily complex command after-c—
up to the complexity of a full-blown shell script —
you might have occasion to use any of the repertoire of builtins;
e.g.,source,read,export,times,setandunset, etc.
The
-coption allows programs to run commands.
It’s a lot easier to fork and doexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);than it is to fork, create a pipe, fork again,
callexeclin each child, callwait, check the exit status,
fork again, callclose(1), open the file,
ensure that it is open on file descriptor 1, and do anotherexecl.
I believe that this was the reason why the option was created
in the first place.The
system()library function runs a command by the above method.- It provides a way to take an arbitrarily complex command
and make it look like a simple command.
This is useful with programs that run a user-specified command,
such asfind … -execorxargs.
But you already knew that; it was part of the answer to your question,
How to specify a compound command as an argument to another command? It can come in handy
if you’re running an interactive shell other than bash.
Conversely, if you are running bash, you can use this syntax$ ash -c "command"
︙
$ csh -c "command"
︙
$ dash -c "command"
︙
$ zsh -c "command"
︙to run one command in another shell,
as all of those shells also recognize the-coption.
Of course you could achieve the same result with$ ash
ash$ command
︙
ash$ exit
$ csh
csh$ command
︙
csh$ exit
$ dash
dash$ command
︙
dash$ exit
$ zsh
zsh$ command
︙
zsh$ exitI used
ash$, etc., to illustrate the prompts from the different shells;
you probably wouldn’t actually get those.It can come in handy
if you want to run one command in a “fresh” bash shell; for example,$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2or
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtinThe above is a misleading over-simplification.
When bash is run with-c, it is considered a non-interactive shell,
and it does not read~/.bashrc, unless is-ispecified. So,$ type cp
cp is aliased to ‘cp -i’ # Defined in ~/.bashrc
$ cp .file1 file2
cp: overwrite ‘file2’? n
$ bash -c "cp .file1 file2"
# Existing file is overwritten without confirmation!
$ bash -c -i "cp .file1 file2"
cp: overwrite ‘file2’? nYou could use
-ci,-i -cor-icinstead of-c -i.This probably applies to some extent to the other shells
mentioned in paragraph 3, so the long form (i.e., the second form,
which is actually exactly the same amount of typing) might be safer, especially if you have initialization/configuration files
set up for those shells.As Wildcard explained, since you’re running a new process tree
(a new shell process and, potentially, its child process(es)),
changes to the environment made in the subshell
cannot affect the parent shell (current directory,
values of environment variables, function definitions, etc.)
Therefore, it’s hard to imagine a shell builtin command
that would be useful when run bysh -c.fg,bg, andjobscannot affect or access background jobs
started by the parent shell, nor canwaitwait for them.sh -c "exec some_program"is essentially equivalent
to just runningsome_programthe normal way,
directly from the interactive shell.sh -c exitis a big waste of time.ulimitandumaskcould change the system settings
for the child process, and then exit without exercising them.Just about the only builtin command that would be functional
in ash -ccontext iskill.
Of course, the commands that only produce output
(echo,printf,pwdandtype) are unaffected,
and, if you write a file, that will persist.- Of course you can use a builtin in conjunction with
an external command; e.g.,sh -c "cd some_directory; some_program"
but you can achieve essentially the same effect with a normal subshell:(cd some_directory; some_program)
which is more efficient.
The same (both parts) can be said for something likesh -c "umask 77; some_program"
orulimit(orshopt).
And since you can put an arbitrarily complex command after-c—
up to the complexity of a full-blown shell script —
you might have occasion to use any of the repertoire of builtins;
e.g.,source,read,export,times,setandunset, etc.
edited 2 days ago
answered Apr 15 '16 at 2:41
G-ManG-Man
13.6k93770
13.6k93770
+1 except I think you go too far on builtins. To be clearecho printf type pwdare builtins; so areset shopt shift read readarray mapfile trap declare/typeset export local let readonly unsetwhich don't affect the parent but may still be useful inside a moderately complicated-c.
– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example ofsh -cbeing used with a complex command line including three programs, a pipe, a&&, and a redirection; I showed an example of it being used with a compound command line including acd, a;, and a program; I showed an example of it being used withexec; and I said it could be used with builtins likeecho,kill,printf,pwdandtype(and alsoexit,ulimit, andumask). What more do you want to know? … (Cont’d)
– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it meanexecve()can operate on a script?”, (1) that has nothing to do withbash -c, and (2) what research have you done? Theexecveman page answers this, and a search of this site yields this, this, this, this, this, and this.
– G-Man
Apr 15 '16 at 22:45
add a comment |
+1 except I think you go too far on builtins. To be clearecho printf type pwdare builtins; so areset shopt shift read readarray mapfile trap declare/typeset export local let readonly unsetwhich don't affect the parent but may still be useful inside a moderately complicated-c.
– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example ofsh -cbeing used with a complex command line including three programs, a pipe, a&&, and a redirection; I showed an example of it being used with a compound command line including acd, a;, and a program; I showed an example of it being used withexec; and I said it could be used with builtins likeecho,kill,printf,pwdandtype(and alsoexit,ulimit, andumask). What more do you want to know? … (Cont’d)
– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it meanexecve()can operate on a script?”, (1) that has nothing to do withbash -c, and (2) what research have you done? Theexecveman page answers this, and a search of this site yields this, this, this, this, this, and this.
– G-Man
Apr 15 '16 at 22:45
+1 except I think you go too far on builtins. To be clear
echo printf type pwd are builtins; so are set shopt shift read readarray mapfile trap declare/typeset export local let readonly unset which don't affect the parent but may still be useful inside a moderately complicated -c.– dave_thompson_085
Apr 15 '16 at 8:06
+1 except I think you go too far on builtins. To be clear
echo printf type pwd are builtins; so are set shopt shift read readarray mapfile trap declare/typeset export local let readonly unset which don't affect the parent but may still be useful inside a moderately complicated -c.– dave_thompson_085
Apr 15 '16 at 8:06
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
What is your point? Did you read my 6th bullet, where I said that builtins are useful in conjunction with external command(s)? Are you saying that I should give more examples in bullet #6?
– G-Man
Apr 15 '16 at 8:56
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
Thanks. Someone said that your reply also answered another question, but is that true?
– Tim
Apr 15 '16 at 15:53
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example of
sh -c being used with a complex command line including three programs, a pipe, a &&, and a redirection; I showed an example of it being used with a compound command line including a cd, a ;, and a program; I showed an example of it being used with exec; and I said it could be used with builtins like echo, kill, printf, pwd and type (and also exit, ulimit, and umask). What more do you want to know? … (Cont’d)– G-Man
Apr 15 '16 at 22:45
@Tim: What question? I see five question marks in that “question”. OK, I’m kidding — a little. What are you still unsure about? I showed an example of
sh -c being used with a complex command line including three programs, a pipe, a &&, and a redirection; I showed an example of it being used with a compound command line including a cd, a ;, and a program; I showed an example of it being used with exec; and I said it could be used with builtins like echo, kill, printf, pwd and type (and also exit, ulimit, and umask). What more do you want to know? … (Cont’d)– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it mean
execve() can operate on a script?”, (1) that has nothing to do with bash -c, and (2) what research have you done? The execve man page answers this, and a search of this site yields this, this, this, this, this, and this.– G-Man
Apr 15 '16 at 22:45
(Cont’d) … If you mean “Does it mean
execve() can operate on a script?”, (1) that has nothing to do with bash -c, and (2) what research have you done? The execve man page answers this, and a search of this site yields this, this, this, this, this, and this.– G-Man
Apr 15 '16 at 22:45
add a comment |
Running bash -c "my command here" vs. just running my command here is primarily different in that the former starts a subshell and the latter runs the commands in the current shell.
As far as built-in commands vs. external commands, it doesn't really relate—anything you can run in the current shell, you can run in a subshell.
There are a number of differences in the effects, however:
- Changes to the environment made in the subshell cannot affect the parent shell (current directory, values of environment variables, function definitions, etc.)
- Variables set in the parent shell that have not been exported will be unavailable in the subshell.
This is far from an exhaustive list of differences, but it contains the key point: you are running a different process with bash -c; it's not the same process as your original shell.
There is also a performance hit incurred by spawning a subshell; this is most relevant if your script is run frequently, or if your command is inside a loop of some kind.
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
add a comment |
Running bash -c "my command here" vs. just running my command here is primarily different in that the former starts a subshell and the latter runs the commands in the current shell.
As far as built-in commands vs. external commands, it doesn't really relate—anything you can run in the current shell, you can run in a subshell.
There are a number of differences in the effects, however:
- Changes to the environment made in the subshell cannot affect the parent shell (current directory, values of environment variables, function definitions, etc.)
- Variables set in the parent shell that have not been exported will be unavailable in the subshell.
This is far from an exhaustive list of differences, but it contains the key point: you are running a different process with bash -c; it's not the same process as your original shell.
There is also a performance hit incurred by spawning a subshell; this is most relevant if your script is run frequently, or if your command is inside a loop of some kind.
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
add a comment |
Running bash -c "my command here" vs. just running my command here is primarily different in that the former starts a subshell and the latter runs the commands in the current shell.
As far as built-in commands vs. external commands, it doesn't really relate—anything you can run in the current shell, you can run in a subshell.
There are a number of differences in the effects, however:
- Changes to the environment made in the subshell cannot affect the parent shell (current directory, values of environment variables, function definitions, etc.)
- Variables set in the parent shell that have not been exported will be unavailable in the subshell.
This is far from an exhaustive list of differences, but it contains the key point: you are running a different process with bash -c; it's not the same process as your original shell.
There is also a performance hit incurred by spawning a subshell; this is most relevant if your script is run frequently, or if your command is inside a loop of some kind.
Running bash -c "my command here" vs. just running my command here is primarily different in that the former starts a subshell and the latter runs the commands in the current shell.
As far as built-in commands vs. external commands, it doesn't really relate—anything you can run in the current shell, you can run in a subshell.
There are a number of differences in the effects, however:
- Changes to the environment made in the subshell cannot affect the parent shell (current directory, values of environment variables, function definitions, etc.)
- Variables set in the parent shell that have not been exported will be unavailable in the subshell.
This is far from an exhaustive list of differences, but it contains the key point: you are running a different process with bash -c; it's not the same process as your original shell.
There is also a performance hit incurred by spawning a subshell; this is most relevant if your script is run frequently, or if your command is inside a loop of some kind.
answered Apr 15 '16 at 0:00
WildcardWildcard
23.2k1067171
23.2k1067171
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
add a comment |
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
1
1
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
FYI, I quoted your answer in my answer. I tried to ping you from there, knowing that that doesn't work.
– G-Man
Apr 15 '16 at 2:46
add a comment |
The -c option basically runs a mini-shell script provided as a CLI argument rather than a file.
$ bash -c the_script the_scriptname 1 2 3
is virtually equivalent to:
$ echo the_script > the_scriptname
$ bash the_scriptname 1 2 3
$ rm the_scriptname
As you can see from:
$ bash -c 'printf " ->%sn" $0 "$@"; echo $-;' scriptname 1 2 3
->scriptname
->1
->2
->3
hBc
(In English:
$0 == scriptname; $@ == (1 2 3);
and bash will:
hash commands; perform Brace expansion, and it has been run with the -c flag)
and:
$ echo 'printf " ->%sn" $0 "$@"; echo $-;' > scriptname
$ bash scriptname 1 2 3
->scriptname
->1
->2
->3
hB
add a comment |
The -c option basically runs a mini-shell script provided as a CLI argument rather than a file.
$ bash -c the_script the_scriptname 1 2 3
is virtually equivalent to:
$ echo the_script > the_scriptname
$ bash the_scriptname 1 2 3
$ rm the_scriptname
As you can see from:
$ bash -c 'printf " ->%sn" $0 "$@"; echo $-;' scriptname 1 2 3
->scriptname
->1
->2
->3
hBc
(In English:
$0 == scriptname; $@ == (1 2 3);
and bash will:
hash commands; perform Brace expansion, and it has been run with the -c flag)
and:
$ echo 'printf " ->%sn" $0 "$@"; echo $-;' > scriptname
$ bash scriptname 1 2 3
->scriptname
->1
->2
->3
hB
add a comment |
The -c option basically runs a mini-shell script provided as a CLI argument rather than a file.
$ bash -c the_script the_scriptname 1 2 3
is virtually equivalent to:
$ echo the_script > the_scriptname
$ bash the_scriptname 1 2 3
$ rm the_scriptname
As you can see from:
$ bash -c 'printf " ->%sn" $0 "$@"; echo $-;' scriptname 1 2 3
->scriptname
->1
->2
->3
hBc
(In English:
$0 == scriptname; $@ == (1 2 3);
and bash will:
hash commands; perform Brace expansion, and it has been run with the -c flag)
and:
$ echo 'printf " ->%sn" $0 "$@"; echo $-;' > scriptname
$ bash scriptname 1 2 3
->scriptname
->1
->2
->3
hB
The -c option basically runs a mini-shell script provided as a CLI argument rather than a file.
$ bash -c the_script the_scriptname 1 2 3
is virtually equivalent to:
$ echo the_script > the_scriptname
$ bash the_scriptname 1 2 3
$ rm the_scriptname
As you can see from:
$ bash -c 'printf " ->%sn" $0 "$@"; echo $-;' scriptname 1 2 3
->scriptname
->1
->2
->3
hBc
(In English:
$0 == scriptname; $@ == (1 2 3);
and bash will:
hash commands; perform Brace expansion, and it has been run with the -c flag)
and:
$ echo 'printf " ->%sn" $0 "$@"; echo $-;' > scriptname
$ bash scriptname 1 2 3
->scriptname
->1
->2
->3
hB
answered Apr 14 '16 at 23:42
PSkocikPSkocik
18.4k553100
18.4k553100
add a comment |
add a comment |
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to
the positional parameters, starting with $0.
This will solve your questions I guess
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
add a comment |
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to
the positional parameters, starting with $0.
This will solve your questions I guess
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
add a comment |
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to
the positional parameters, starting with $0.
This will solve your questions I guess
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to
the positional parameters, starting with $0.
This will solve your questions I guess
answered Apr 14 '16 at 23:21
rɑːdʒɑrɑːdʒɑ
2,66472753
2,66472753
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
add a comment |
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
thanks. can you explain explicitly to my questions?
– Tim
Apr 14 '16 at 23:27
add a comment |
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%2f276581%2fwhat-is-the-difference-between-running-a-command-directly-and-with-bash-c%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
