LINUX.ORG.RU

Как в os.system() экранировать специальные символы? Не могу написать bash-промпт PS1

 , , , ,


0

1

Мне нужно вызвать окно xterm с запущенным bash так, чтобы в нем было специальное приглашение ввода (оно же prompt).

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

xterm -geometry 160x50 -sb -e "tty ; export PS1=\"\\u-\\h:\\W\\> \" ; bash -norc"

И нужно эту команду запустить из Python-скрипта, через os.system(). Я пробую сделать так:
#!/usr/bin/python3
import os
os.system('xterm -geometry 160x50 -sb -e "tty ; export PS1=\"\\u-\\h:\\W\\> \" ; bash -norc"')

Однако в этом случае xterm стартует с ошибкой:
xterm: Can't execvp tty ; export PS1=u-h:W>: Нет такого файла или каталога

И промпт, естественно, остается не настроенным.

Вопрос: как правильно засунуть все нужные символы в строку, которая будет выполнена через os.system() ?

Я пробовал и двойное экранирование, и даже через chr(0x5C) передавал обратный слеш во всяких разных комбинациях, нащупать правильную строку так и не смог.

★★★★★

не знаю, что ты там и как экранировал, но так работает:

os.system('xterm -geometry 160x50 -sb -e "tty ; export PS1=\\"\\u-\\h:\\W\\> \\" ; bash -norc"')
Sahas ★★★★☆
()

Я может чего-то не понимаю, но кажется для такого предполагается subprocess использовать

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Всё правильно, многие низкоуровневые функции из os в Python 3 заменяют на высокоруровневые, например, pathlib, subprocess. Но os остаётся для совместимости.

emorozov
()
Ответ на: комментарий от AntonI

Нет, я такого не писал. subprocess — более удобная альтернатива os.system и прочим подобным старым интерфейсам для порождения процессов.

emorozov
()
Ответ на: комментарий от emorozov

Эх… а я думал все за нас уже сделали.

Насчет удобства - от задачи зависит. Возможностей у subprocess конечно больше, но и букофф в коде тоже больше выходит.

AntonI ★★★★★
()
Ответ на: комментарий от Sahas

Да, я так пробовал, у мен не работало. В понедельник проверю.

Xintrea ★★★★★
() автор топика

сначала setenv(«PS1»,«my super puper promop»);

потом os.system

переменные окружения НАСЛЕДУЮТСЯ

PS/ про то что xterm`у лучше указать что запускается bash и что ему не стоит исполнять rc (-norc) выше сказали

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

В subprocess это по-нормальному это сделано, не надо делать setenv и трогать всё окружение.

kukuruku ★★
()
Ответ на: комментарий от kukuruku

WTF «правильно»? Чем os.system неправильно?

$ python3
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> help(os.system)
Help on built-in function system in module posix:

system(command)
    Execute the command in a subshell.

Где здесь хоть слово о том что это неправильно?!

Что касается «как принято» то вообще не аргумент. В разных местах решают очень разные задачи и принято тоже очень по разному.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от AntonI

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

https://docs.python.org/3/library/os.html

Старый код может трогать и не надо. Но если что-то новое пишется, то лучше использовать общепринятые и современные инструменты.

kukuruku ★★
()

А может заменить эту плохочитаемую шляпу на пару вызовов spawnlp? Там аргументы передаются просто как параметры метода

cobold ★★★★★
()
Ответ на: комментарий от t184256

Непереносима куда? Я не пишу под вин.

Небезопасна по сравнению с subprocess?

Не рекомендуется - вообще пофик, вот честно. Пока она не обьявлена официально deprecated.

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

deprecated она будет, только когда переведутся те, кому «вообще пофик, вот честно», ведь их хай будет звенеть в ушах и мешать планировать остальные изменения в Python 4.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

100% изменений в py3 сломавших обратную совместимость были ненужны.

А так, как будет deprecated так приходи с советами.

AntonI ★★★★★
()
Ответ на: комментарий от kukuruku

на пистоне писать все эти вызовы консольных утилит боль, поэтому шел живее всех живых.

uwuwuu
()
Ответ на: комментарий от t184256

так различия только в том, что с os.system, тебе не нужен вывод, а только код.

А под капотом там, наверное, магия, сводящееся к записи куда-то в память, те работе с файлами. Как в этом случае с вызовом asm:

import ctypes
import mmap

buf = mmap.mmap(-1, mmap.PAGESIZE, prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)

ftype = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
fpointer = ctypes.c_void_p.from_buffer(buf)

f = ftype(ctypes.addressof(fpointer))

buf.write(
    b'\x8b\xc7'  # mov eax, edi
    b'\x83\xc0\x01'  # add eax, 1
    b'\xc3'  # ret
)

r = f(42)
print(r)

del fpointer
buf.close()

хотя я тупллю… там в исходниках просто сишный system

uwuwuu
()
Последнее исправление: uwuwuu (всего исправлений: 1)

print(setSTR:=r'xterm -geometry 160x50 -sb -e "tty ; export PS1=\"\\u-\\h:\\W\\> \" ; bash -norc"')

__import__('os').system(setSTR)
qulinxao3
()
Ответ на: комментарий от Sahas

os.system('xterm -geometry 160x50 -sb -e «tty ; export PS1=\\»\\u-\\h:\\W\\> \\" ; bash -norc"')

Проверил, работает. Я не делал двойного экранирования у кавычек, которые внутри кавычек, двойное делал только внутри этих кавычек, в этом и была проблема. И еще выяснилось что символ «>» экранировать вообще ненужно, чтобы перед ним лишней обратной косой не появлялось. Он не будет трактоваться как перенаправление ввода, потому что в конечной строке он оказывается внутри кавычек.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от kukuruku

Старый код может трогать и не надо. Но если что-то новое пишется, то лучше использовать общепринятые и современные инструменты.

Они не всегда работают как ожидается:

Xterm в Tk. Почему не каждый цветной терминальный вывод отображается через Popen+communicate?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от kukuruku

Может ты просто не разобрался до конца? Что там не работает, как ожидается?

В данном случае цветной вывод. В таком устаревшем и неправильном os.system() он, неожиданно, работает прекрасно. А в таком правильном Popen+communicate - возникают внезапные проблемы: одна программа покажет цветной вывод, другая - нет. Я, конечно, разобрался что за дичь происходит, но осадочек остался.

Xintrea ★★★★★
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.