pythonshellglobexpansionplumbum

Avoid escaping glob expressions in plumbum


Suppose I want to run something like ls a* using plumbum.

from plumbum.cmd import ls
ls['a*']()
...
ProcessExecutionError: Command line: ['/bin/ls', 'a*']
Exit code: 1
Stderr:  | ls: a*: No such file or directory

I understand plumbum automatically escapes the arguments, which is usually a good thing. But is there a way to make it understand glob expressions should be passed to the shell as-is?


Solution

  • But is there a way to make it understand glob expressions should be passed to the shell as-is?

    plumbum passes a* to ls command as-is. ls command doesn't run any shell, so there is no glob expansion (it is done by the shell on *nix).

    You could use glob module to do the expansion:

    from glob import glob
    
    ls('-l', *glob('a*'))
    

    Another way is to use Workdir object:

    from plumbum import local
    
    ls('-l', *local.cwd // 'a*')
    

    To defer the call; you could use ls['-l'][args] syntax (note: there is probably a bug in plumbum 1.1.0 version that requires to convert args list to a tuple explicitly).

    If you want; you could call the shell:

    from plumbum.cmd import sh
    
    sh('-c', 'ls -l a*')
    

    Note: Python's glob.glob() function might produce the glob expansion different from that of the shell.