imagineerThat
imagineerThat

Reputation: 5553

when to use bash with option -c?

I'm trying to understand -c option for bash better. The man page says:

-c: If the -c option is present, then commands are read from the first non-option argument command_string. If there are arguments after the command_string, they are assigned to the positional parameters, starting with $0.

I'm having trouble understanding what this means.

If I do the following command with and without bash -c, I get the same result (example from http://www.tldp.org/LDP/abs/html/abs-guide.html):

$ set w x y z; IFS=":-;"; echo "$*"
w:x:y:z
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

Upvotes: 5

Views: 4540

Answers (3)

Charles Duffy
Charles Duffy

Reputation: 295736

bash -c isn't as interesting when you're already running bash. Consider, on the other hand, the case when you want to run bash code from a Python script:

#!/usr/bin/env python
import subprocess
fileOne='hello'
fileTwo='world'

p = subprocess.Popen(['bash', '-c', 'diff <(sort "$1") <(sort "$2")',
                      '_',     # this is $0 inside the bash script above
                      fileOne, # this is $1
                      fileTwo, # and this is $2
                     ])
print p.communicate() # run that bash interpreter, and print its stdout and stderr

Here, because we're using bash-only syntax (<(...)), you couldn't run this with anything that used POSIX sh by default, which is the case for subprocess.Popen(..., shell=True) or os.system(...); using bash -c thus provides access to capabilities that wouldn't otherwise be available without playing with FIFOs yourself.


Incidentally, this isn't the only way to do that: One could also use bash -s, and pass code in on stdin. Below, that's being done not from Python but POSIX sh (/bin/sh, which likewise is not guaranteed to have <(...) available):

#!/bin/sh

# ...this is POSIX sh code, not bash code; you can't use <() here
# ...so, if we want to do that, one way is as follows:

fileOne=hello
fileTwo=world

bash -s "$fileOne" "$fileTwo" <<'EOF'
# the inside of this heredoc is bash code, not POSIX sh code
diff <(sort "$1") <(sort "$2")
EOF

Upvotes: 6

John Bollinger
John Bollinger

Reputation: 181459

The -c option finds its most important uses when bash is launched by another program, and especially when the code to be executed may or does include redirections, pipelines, shell built-ins, shell variable assignments, and / or non-trivial lists. On POSIX systems that have /bin/sh being an alias for bash, it specifically supports the C library's system() function.

Equivalent behavior is much trickier to implement on top of fork / exec without using -c, though not altogether impossible.

Upvotes: 2

ForceBru
ForceBru

Reputation: 44886

How to execute BASH code from outside the BASH shell?

The answer is, using the -c option, which makes BASH execute whatever that has been passed as an argument to -c.

So, yeah, this is the purpose of this option, to execute BASH code arbitrarily, but just in another way.

Upvotes: 1

Related Questions