python не распечатывает символ " - PullRequest
3 голосов
/ 07 августа 2020

У меня странная проблема. Мне нужно распечатать строку вывода из команды stat.

Я написал код, который получает некоторую информацию.

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}")

Ожидаемый результат:

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

Но мой вывод выглядит так:

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

Он не напечатал там ни одного ". Почему так? Я попытался заменить "на", и это работает, но мне это не нужно.

1 Ответ

2 голосов
/ 07 августа 2020

os.system() вызывает оболочку, которая выполняет свою собственную обработку кавычек поверх того, что уже делает Python. Вы можете backsla sh -экранировать кавычки как из Python, так и из оболочки, но это быстро становится сложным, потому что вам нужно backsla sh -escape escapesla sh, предназначенных для оболочки, из Python.

Правильное цитирование будет выглядеть примерно так:

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}""")

, где мы используем тройные кавычки Python, чтобы позволить нам передавать в оболочку как буквальные одинарные, так и двойные кавычки.

Конечно, гораздо лучшим решением является использование subprocess, которое позволяет вам полностью обойти оболочку.

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)

Но если все ваши фактические бизнес-логики c в любом случае находятся в сценарии оболочки, почему вы вообще используете Python?

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

(вам может потребоваться разбить это на xargs, если глобус возвращает большое количество совпадений.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...