Search code examples
pythonbashmacosffmpeg

How to add escape characters to a filename to be consumed later by a shell command?


I am trying to find out which of my video files are corrupted. I loop through a directory, grab each video file, and check if it is corrupt/healthy. If the filename has no spaces nor special characters, it will work. Unfortunately, many of my files have spaces or parenthesis in the name, and this causes my shell command ffmpeg within my python script to fail. How can I retrieve the filenames in abs_file_path with the escape characters preceding the special characters?

Example filename: Movie Name (1080p)

Goal: Movie\ Name\ \(1080p\)

for filename in os.listdir(directory):
    if filename.endswith(tuple(VIDEO_EXTENSIONS)):
        print(f'PROCESSING: {filename}...')

        abs_file_path = os.path.join(directory, filename)

        proc = subprocess.Popen(f'./ffmpeg -v error -i {abs_file_path} -f null - 2>&1', shell=True, stdout=subprocess.PIPE)
        output = proc.communicate()[0]

        row = ''
        if not output:
            # Healthy
            print("\033[92m{0}\033[00m".format("HEALTHY -> {}".format(filename)), end='\n')  # red
            row = [filename, 0]
        else:
            # Corrupt
            print("\033[31m{0}\033[00m".format("CORRUPTED -> {}".format(filename)), end='\n')  # red
            row = [filename, 1]

        results_file_writer.writerow(row)
        results_file.flush()

results_file.flush()
results_file.close()

Solution

  • You can use shlex.quote() .

    A simple example —

    # cat run.py
    import shlex, subprocess
    
    fname = 'Movie Name (1080p)'
    shcmd = 'ls -l %s' % shlex.quote(fname)
    
    print('shcmd:', shcmd)
    subprocess.run(shcmd, shell=True)
    
    # python3 run.py
    shcmd: ls -l 'Movie Name (1080p)'
    -rw-r--r--  1 pynexj  staff  0 Mar  9 09:55 Movie Name (1080p)