Reputation: 43487
Context: I ran this snippet on my Mac and noticed the string -n
sprinkled in the garbled output. The answer is that sh
on Ubuntu understands the -n
flag while sh
on my Mac does not.
As you can see, python is sending to stdout the string "-n abc\n"
rather than the expected "abc"
.
Is the os.system
call unable to separate -n
and abc
? Happens with both zsh (the inverted %
is zsh's way of indicating an EOF) and bash, though if I am not mistaken no shells should be invoked by the python-call (not because I read anything that says so, but based on my common sense) (edit: turns out i'm totally wrong and system runs a subshell)
See how ruby does:
And some more testing:
Looks like the script is sent to
sh
but the environment variable for the shell at that point is still zsh
. Makes sense. I did nothing to clean out the environment... Maybe sh
doesnt automatically set $SHELL
.
Upvotes: 2
Views: 242
Reputation: 587
what about this?
python -c 'import subprocess; subprocess.call(["echo", "-n", "abc"])'
tested on osx and working properly
Upvotes: 0
Reputation: 258388
The Python docs state:
[
os.system
] is implemented by calling the Standard C function system()
Follow through to the man page for C's system
:
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.
Emphasis is mine.
The man page for echo explains it:
Some shells may provide a builtin echo command which is similar or identical to this utility. Most notably, the builtin echo in sh(1) does not accept the -n option. Consult the builtin(1) manual page.
And you can confirm this yourself:
$ sh -c "echo -n hello"
-n hello
$ bash -c "echo -n hello"
hello
Upvotes: 2
Reputation: 179592
As noted in the documentation, os.system
executes the command in a subshell. Depending on your system, it may use a shell whos echo
command doesn't understand -n
.
If you want to ensure it uses your shell of choice, use subprocess.call
with the shell=True
and executable='<shell>'
options instead of os.system
.
Upvotes: 0