简体   繁体   中英

find file with variable name in python script

I am trying to execute the find command in a python script, using a for loop to pass a variable index determining the specific file name to find. I am using the following syntax, which in python returns an empty set, however works in the terminal:

for j in [1,2,3,5]:  
    file_name = cmd.getoutput('find . -type f -name "*${j}-xyz.stc" -printf "%f\n"')

Obviously, the variable is not being passed to the find expression in my python code, but how can I remedy that? Any suggestions are appreciated.

variables aren't expanded in python the same as they are in bash. You probably want:

command = r'find . -type f -name "*{0}-xyz.stc" -printf "%f\n"'.format(j)
file_name = cmd.getoutput(command)

Also note that the commands module is deprecated in favor of subprocess . Finally, it should probably be pointed out that you could write this function in python without relying on find if you used os.walk in conjunction with glob.glob .

untested, but something like this should be close ...

import os
import glob

def find_files(glob_expr):
    for root,_,_ in os.walk(os.curdir):
        for fname in glob.iglob(os.path.join(os.curdir,root,glob_expr)):
            yield fname
for i in (1,2,3,4):
    print (list(find_files('{0}-xyz.stc'.format(i))))
file_name = cmd.getoutput('find . -type f -name "*%i-xyz.stc" -printf "%%f\n"' % (j))

Passing filenames in a string to the shell is unsafe (leads to potentially security-impacting bugs). Best practice is to pass an explicit argv list:

import subprocess
for j in range(1, 6):
    file_name = subprocess.check_output(['find', '.', '-type', 'f', '-name',
                                         '*%s-xyz.stc' % (j,),
                                         '-printf', '%f\\n'])

If you really care about correctness (and you should!), use '%f\\\\0' as your format string, and expect your outputs to be NUL-separated. Otherwise, you can't tell the difference between a file with a newline in its name and two files returned.

To appreciate the importance, consider the case where an attacker can persuade software running on your system to create a file named like so:

/your/top/dir/$'\n'/etc/passwd$'\n'/1-xyz.stc

If you treat each line returned by find as a filename, you would consider /etc/passwd to be part of your returned values -- a very bad thing if you then present this data to the user, delete it, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM