Search code examples
pythonsubprocessaliascshos.system

Overcoming os.system() limitation in Python 2.3


I am having a problem converting one of my company's scripts from csh to Python. The csh script calls an aliased command, but when I call that same aliased command via os.system(), it does not work.

So, if foo is the aliased command:

CSH Script (this works, executes foo):

foo <argument>

Python (this does not work, error claims foo is an unknown command):

os.system("foo <argument>")

I figure there must be some kind of context switch happening when I execute the python script, which causes Python to not have access to the aliases created in the shell. After reading the documentation, it seems that os.system is being deprecated in favor of subprocess, and that subprocess has a shell parameter that might be able to help me out...problem is that I'm stuck using Python 2.3, and subprocess isn't available until version 2.4.

I had the idea to replicate the alias in python. So, for example, say foo was aliased to cp.

CSH:

alias foo cp
foo file1 file2

Python:

os.system("alias foo cp")
os.system("foo file1 file2")

No dice...errors here as well:

sh: line 0: alias: foo: not found
sh: line 0: alias: cp: not found
sh: foo: command not found

My last ditch effort is to take the few lines of code that use foo and put them into their own CSH script that Python would call. But if there's a way to make this work without resorting to that, I'd love to know about it.

Thanks in advance!


Solution

  • What made you think os.system would use csh? It uses standard C function system, that on Unix system will call just basic /bin/sh. This will not be csh, but most probably bash, or some simpler version of it.

    BTW: note that what you do with shell environment in os.system will not affect subsequent calls to os.system, because each is run in different subshell. In other words, changes made to the environment are lost. And your call to alias fails, because /bin/sh uses different syntax for aliases than csh.

    You could workaround this by running not foo, but something along the lines:

    os.system("/bin/csh -i -c 'foo arg1 arg2'")
    

    Note the option -i which is supposed to force csh to read startup scripts.