python does not print out " character

Viewed 67

I have a weird problem. I need to print out an output string from the stat command.

I've written the code that obtains some of the info.

import glob
import os

for file in glob.glob('system1/**', recursive=True):
    os.system("stat -c \"set_metadata(/%n \"uid\", %u, \"gid\", %g, \"mode\", 0%a, \"capabilities\", 0x0, \"selabel\", \"later\");\" "f"{file}")

Expected output:

set_metadata("/system1/xbin/jack_transport" "uid", 0, "gid", 2000, "mode", 0755, "capabilities", 0x0, "selabel", "later");

But my output looks like this:

set_metadata(/system1/xbin/jack_transport uid, 0, gid, 2000, mode, 0755, capabilities, 0x0, selabel, later);

It did not print a single " in there. Why so? i have tried replacing " with ' and that works but that's not what I need.

1 Answers

os.system() invokes the shell, which does its own quote processing on top of what Python already does. You can backslash-escape quotes from both Python and the shell, but it quickly gets complex because you have to backslash-escape the backslash escapes intended for the shell from Python, too.

Proper quoting would look something like

for file in glob.glob('system1/**', recursive=True):
    os.system(f"""stat -c 'set_metadata(/%n "uid", %u, "gid", %g, "mode", 0%a, "capabilities", 0x0, "selabel", "later");' {file}""")

where we use Python's triple quotes to allow us to pass both literal single and double quotes to the shell.

Of course, a much better solution is to use subprocess, which allows you to bypass the shell completely.

for file in glob.glob('system1/**', recursive=True):
    subprocess.run(['stat', '-c',
      'set_metadata(/%n "uid", %u, "gid", %g, "mode", 0%a, "capabilities", 0x0, "selabel", "later");',
      file], check=True)

But if all your actual business logic is in shell script anyway, why are you using Python at all?

#!/bin/bash
stat -c 'set_metadata(/%n "uid", %u, "gid", %g, "mode", 0%a, "capabilities", 0x0, "selabel", "later");\n' system1/**

(You might need to break this up with xargs if the glob returns a large number of matches.)

Related