without shell

S

Steven D'Aprano

hi all,

can any linux command be invoked/ executed without using shell (bash) ?

py> import os
py> status = os.system("ls")

Prints the output of ls and stores the exit code into status.

py> file_list = os.popen("ls").read()

Stores the output of ls into file_list.

Or see the module "commands".
what abt security concerns ?

Yes, there are serious security concerns. You should be *very* careful
about executing strings generated by users. You probably don't want your
program executing something like os.system("rm -rf /").
 
G

Grant Edwards

can any linux command be invoked/executed without using shell (bash)?

Yes -- for some values of "linux command". You can execute
anything that's not a bash internal or a bash script without
using bash.
what abt security concerns?

What about them?
 
G

Grant Edwards

py> import os
py> status = os.system("ls")

Prints the output of ls and stores the exit code into status.

It's done by invoking the user's SHELL and passing the string
"ls" to it. In the general case, invoking an unknown shell and
passing it a string is fraught with peril.
py> file_list = os.popen("ls").read()

Stores the output of ls into file_list.

That also executes a shell (same as os.system()), so it's
equally as unreliable and insecure as os.system(). [See the
notes at http://docs.python.org/lib/os-newstreams.html#os-newstreams
that describe popen.]
Or see the module "commands".


Yes, there are serious security concerns. You should be *very* careful
about executing strings generated by users. You probably don't want your
program executing something like os.system("rm -rf /").

You've got also got a much better chance of getting what you
expect if you don't invoke a shell, but use os.spawn*
functions instead.
 
M

Mage

Steven said:
py> import os
py> status = os.system("ls")

Prints the output of ls and stores the exit code into status.

py> file_list = os.popen("ls").read()

Stores the output of ls into file_list.
These commands invoke shell indeed.

Mage
 
S

Steven D'Aprano

It's done by invoking the user's SHELL and passing the string
"ls" to it. In the general case, invoking an unknown shell and
passing it a string is fraught with peril.

Ah... you learn something new every day.

I interpreted the original question as meaning "can Python execute
arbitrary Linux commands without exiting the Python interpretor and
dropping into a shell prompt?".
 
D

Donn Cave

Grant Edwards said:
Under Unix, popen will not invoke a shell if it's passed a
sequence rather than a single string.

I suspect you're thinking of the popen2 functions.
On UNIX, os.popen is posix.popen, is a simple wrapper
around the C library popen. It always invokes the
shell.

The no-shell alternatives are spawnv (instead of
system) and the popen2 family (given a sequence
of strings.)

Donn Cave, (e-mail address removed)
 
G

Grant Edwards

I suspect you're thinking of the popen2 functions.

According to the current module reference, that's the behavior
of the os.popen*() functions:

http://docs.python.org/lib/os-newstreams.html#os-newstreams
On UNIX, os.popen is posix.popen, is a simple wrapper around
the C library popen. It always invokes the shell.

Not according the the docs:

Also, for each of these variants, on Unix, cmd may be a
sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()).
If cmd is a string it will be passed to the shell (as with
os.system()).

It's not exactly clear what "these variants" refer to, but I
read it as referring to all of the the os.popen functions.

Perhaps it only refers to os.popen[234]?
 
D

David M. Cooke

Donn Cave said:
I suspect you're thinking of the popen2 functions.
On UNIX, os.popen is posix.popen, is a simple wrapper
around the C library popen. It always invokes the
shell.

The no-shell alternatives are spawnv (instead of
system) and the popen2 family (given a sequence
of strings.)

Don't forget the one module to rule them all, subprocess:

file_list = subprocess.Popen(['ls'], stdout=subprocess.PIPE).communicate()[0]

which by default won't use the shell (unless you pass shell=True to it).
 
D

Donn Cave

Grant Edwards said:
According to the current module reference, that's the behavior
of the os.popen*() functions:

http://docs.python.org/lib/os-newstreams.html#os-newstreams
On UNIX, os.popen is posix.popen, is a simple wrapper around
the C library popen. It always invokes the shell.

Not according the the docs:

Also, for each of these variants, on Unix, cmd may be a
sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()).
If cmd is a string it will be passed to the shell (as with
os.system()).

It's not exactly clear what "these variants" refer to, but I
read it as referring to all of the the os.popen functions.

Perhaps it only refers to os.popen[234]?

Right. The paragraphs seem a little scrambled. Note
the use of "cmd" instead of "command" as the parameter
is named for popen(). Also note "These methods do not
make it possible to retrieve the return code from the
child processes", after the popen() paragraph above tells
you how to do it (using the better term "exit status".)

Or one may look at the source.

Donn Cave, (e-mail address removed)
 
G

Grant Edwards

Also, for each of these variants, on Unix, cmd may be a
sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()).
If cmd is a string it will be passed to the shell (as with
os.system()).

It's not exactly clear what "these variants" refer to, but I
read it as referring to all of the the os.popen functions.

Perhaps it only refers to os.popen[234]?

Right. The paragraphs seem a little scrambled. Note
the use of "cmd" instead of "command" as the parameter
is named for popen(). Also note "These methods do not
make it possible to retrieve the return code from the
child processes", after the popen() paragraph above tells
you how to do it (using the better term "exit status".)

Or one may look at the source.

Or write a 3-line test to see how it really does works. :)
 
R

Reinhold Birkenfeld

Donn said:
Not according the the docs:

Also, for each of these variants, on Unix, cmd may be a
sequence, in which case arguments will be passed directly to
the program without shell intervention (as with os.spawnv()).
If cmd is a string it will be passed to the shell (as with
os.system()).

It's not exactly clear what "these variants" refer to, but I
read it as referring to all of the the os.popen functions.

Perhaps it only refers to os.popen[234]?

Right. The paragraphs seem a little scrambled. Note
the use of "cmd" instead of "command" as the parameter
is named for popen(). Also note "These methods do not
make it possible to retrieve the return code from the
child processes", after the popen() paragraph above tells
you how to do it (using the better term "exit status".)

Or one may look at the source.

FYI, I checked in a little fix to the docs which makes clear
what functions the paragraphs pertain to. Also, I changed
"return code" to "exit status".

Reinhold
 
K

km

hi all,

can any linux command be invoked/ executed without using shell (bash) ?
what abt security concerns ?

regards,
KM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,241
Messages
2,571,219
Members
47,852
Latest member
PatriciaMu

Latest Threads

Top