3

I have just been playing around with IPython. Currently I am wondering how it would be possible to run a shell-command with a python variable within a function. For example:

def x(go):
    return !ls -la {go}

x("*.rar")

This gives me "sh: 1: Syntax error: end of file unexpected". Could anybody please give me a clue on how to let my "x"-function invoke ls like "ls -la *.rar"? There are *.rar files in my working directory.

Thank you in advance, Rainer

5 Answers 5

7

If you look at the history command output, you'll see that to call external programs ipython uses _ip.system method.

Hence, this should work for you:

def x(go):
    return _ip.system("ls -la {0}".format(go))

However, please note that outside ipython you should probably use subprocess.Popen.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi and thx for your quick response! I just tried it and found out, that ''_ip'' needs to be acquired by "_ip = get_ipython()". However, actually that does not parse the output of "ls". I think I will continue to use subprocess.Popen() which is, sadly, not as convenient as "!" in IPython. Cheers, Rainer
If you assign the result of a system command to a variable files = !ls -la, it gets translated to files = get_ipython().getoutput('ls -la foo').
@jcollado: subprocess.Popen is probably overkill for something like this. Have a look at the module-level functions like subprocess.check_output: docs.python.org/library/subprocess#subprocess.check_output
1

There was a bug in the "!" shell access that made the expansion of "function scoped variables" fail. Your ipython's version might be affected.

You can avoid it by doing yourself the variable expansion:

def x(go):
    return get_ipython().getoutput("ls -la {0}".format(go))

Comments

0

While subprocess.Popen is probably the way to go as @jcollado said, just for completeness there is the os.system command to immediately send a command to the shell. However, the subprocess module is almost always a better choice than os.system or os.spawn.

Also, depending on what you are trying to do you may want to use python commands to interact with the operating system rather than passing commands out to a shell. If you want to deal with lists of files for instance, os.walk would likely result in cleaner and more portable code than grabbing the directory list through shell commands. You can look at the documentation for Python's OS module here.

Comments

0

Depending on what you wanted to accomplish, this may be the better way:

In [50]:  %alias x ls -la %l


In [51]:  x *.rar

          -rw-r--r-- 1 dubbaluga users 45254 Apr  4 15:12 schoolbus.rar

Comments

0

Maybe its easier to use Python for this case:

import glob

files = glob.glob('*.rar')   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.