ls , as it works through Python, is probably right: I think that in the current directory there is no file named *CSV*APP* . There is probably a file with a name that matches this glob pattern. But ls doesn't care about balls. What happens when you run the command in the shell is that the shell extends glob to match the names of the files that it can see in the current directory, and these extended names are what the shell passes to ls .
To get the same result in the shell as in Python (for demonstration, not because you need it), protect the arguments from the glob extension with single quotes:
ls -lh '*CVS*APP*'${e}'.zip'
But how can you get shell behavior in Python? You can use shell=True , as some other answers suggest, but this is a slippery slope, since accessing the real shell of your dynamically generated strings (it may depend on user input in a more complex application) can make you vulnerable to command injections and other nasty things .
Here you need only one specific shell behavior, the globbing file name. And Python can do this on its own :
import subprocess as sp from glob import glob sp.call(['cd', input_dir]) for i, e in enumerate(piv_id_list): proc_out = sp.Popen(['ls', '-lh', glob('*CSV*APP*{0}.zip'.format(e))]) proc_out_list.append(proc_out) print(proc_out)
As JunCompressor pointed out , it will still look in the wrong directory, because cd will only affect the subdial of the cd call, so let's fix this too:
import subprocess as sp from glob import glob os.chdir(input_dir) for i, e in enumerate(piv_id_list): proc_out = sp.Popen(['ls', '-lh', glob('*CSV*APP*{0}.zip'.format(e))]) proc_out_list.append(proc_out) print(proc_out)
The note
Perhaps you can use a slightly higher level of sp.check_output instead of lower sp.Popen .