В скрипте Python у меня есть функция, которая выглядит следующим образом:
def NotifierFunc(Mail, Ticket_Num, Open_DtTime):
cmd = "/home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message 'Hello <at>"+Mail+"<at> : The ticket <a href='`echo 'http://snview/'"+Ticket_Num+">`echo "+Ticket_Num+"`</a> is not closed for more than 72 hours : Open since "+Open_DtTime+" IST. Please close asap.' "
print(cmd)
subprocess.Popen(cmd, shell= True, stout=subprocess.PIPE)
Что он печатает:
/home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message 'Hello <at>[email protected]<at> : The ticket <a href='`echo 'http://snview/'INC23548>`echo INC23548`</a> is not closed for more than 72 hours : Open since 4-APR-2024 12:30:40 IST. Please close asap.'
Эта команда не выполняется успешно в оболочке главным образом потому, что сообщение (все, что передается после «--message», заключено в одинарные кавычки) или, по крайней мере, я так думаю. Когда я помещаю это в двойные кавычки, скрипт Python выдает синтаксическую ошибку. Когда я помещаю все значение cmd в одинарную кавычку или строку документа quote(''') и содержимое --message в двойную кавычку, это также приводит к синтаксической ошибке.
Если я запускаю команду cmd непосредственно в командной строке Linux (с содержимым --message в двойных кавычках), все работает нормально:
> Mail = "[email protected]"
> Ticket_Num = "INC23548"
> Open_DtTime = "14-APR-2024 12:30:40"
> /home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message "Hello <at>$Mail<at> : The ticket <a href='`echo 'http://snview/'$Ticket_Num >`echo $Ticket_Num`</a> is not closed for more than 72 hours : Open since $Open_DtTime IST. Please close asap."
Теперь мой вопрос заключается в том, как я могу передать все это значение cmd в подпроцесс, чтобы содержимое «--message» могло быть отображено правильно, или как я могу поместить содержимое «--message» в двойные кавычки и заставить его работать.
Обратите внимание, что если я передам cmd, как показано ниже, он работает нормально, но у него нет гиперссылки на номер билета. Но мне нужна гиперссылка.
cmd = "/home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message 'Hello <at>"+Mail+"<at> : The ticket +Ticket_Num+" is not closed for more than 72 hours : Open since "+Open_DtTime+" IST. Please close asap.' "
Я также пробовал помещать переменные в {} и пробовал различные комбинации кавычек. Пока ничего не работает. Я использую Python 3.10
возможно, получите строку, отображаемую print(cmd)
, и попробуйте запустить ее непосредственно в shell
, чтобы проверить, правильна ли она. Как по мне, у вас есть ошибки в HTML
- у них есть '
, что, возможно, должно быть \'
. Вы также можете показать эту строку. Возможно, понадобится еще \\"
или \\'
всегда помещайте ПОЛНОЕ сообщение об ошибке (начиная со слова «Traceback») в вопросе (не в комментариях) в виде текста (не скриншота и не ссылки на внешний портал). В полной версии ошибки/трассировки есть и другая полезная информация.
Кстати: иногда проще создать только строку с сообщением, а затем поместить ее в полную строку с помощью cmd
@furas: Да, я пробовал печатать — печатается нормально, за исключением HTML-части. Я также пробовал запустить его в командной строке Linux. Просто отредактировал свой вопрос, чтобы добавить именно то, что я запускал из командной строки. Ошибка просто означает синтаксическую ошибку. Позвольте мне попытаться указать именно то, что он показывает, когда я печатаю с помощью скрипта Python.
@HåkonHægland: добавлено то, что я запускаю из командной строки Linux. Спасибо
покажите этот отпечаток, о котором идет речь (не в комментариях) - возможно, нужно только добавить \ или \\
честно говоря, я не понимаю, почему вы используете echo
в коде Python. Почему бы не помещать значения непосредственно в строку в Python.
показать также результат print( cmd )
. ИЛИ создайте minimal working code
с примерами данных, чтобы мы могли просто скопировать и запустить его.
@furas: только что добавил результат печати (cmd)
во-первых: вам не нужен echo
в коде. Во-вторых: поскольку сообщение находится ' '
, вам нужно \'
внутри этого сообщения href=\'.... \'
- полное сообщение f" .... --message 'Hello <at>{Mail}<at> : The ticket <a href=\'http://snview/{Ticket_Num}\'>{Ticket_Num}</a> is not closed for more than 72 hours : Open since {Open_DtTime} IST. Please close asap.'"
1) Если у вас нет (неизбежной) необходимости в оболочке, не используйте ее. 2) Для этого длинного «сообщения» я сначала готовил строку, а затем использовал ее для формирования команды. (3) В этом «сообщении» происходит слишком много всего. Почему обратные кавычки? Почему эхо? Так много цитат, даже '
внутри '
(4) В новых версиях Python можно использовать run
вместо Popen
subprocess.Popen принимает список в качестве первого аргумента, что упрощает обработку и интерполяцию строк. Вместо того, чтобы экранировать некоторые последовательности, потому что другие содержат кавычки или двойные кавычки, разделите их, как в примерах из документации.
Я создал тестовый сценарий Perl, который просто печатает каждый аргумент для запуска из Python.
#!/usr/bin/env perl
use feature qw(say);
say for @ARGV;
И выполнить его из Python вот так
#!/usr/bin/env python
import subprocess
import sys
def NotifierFunc(Mail, Ticket_Num, Open_DtTime):
cmd = [
"./main.pl",
"--channel",
"MyChannel",
"--userid",
"itsme",
"--message",
f'Hello <at>{Mail}<at> : The ticket <a href = "http://snview/{Ticket_Num}">{Ticket_Num}</a>'
f" is not closed for more than 72 hours : Open since {Open_DtTime} IST. Please close asap.",
]
subprocess.Popen(cmd, shell=False, stdout=sys.stdout)
if __name__ == "__main__":
NotifierFunc("[email protected]", "INC23548", "14-APR-2024 12:30:40")
Обратите внимание, что я установил shell
на False
и изменил stdout
, чтобы проверить ваш пример и посмотреть, что он напечатает. Я также внес некоторые другие изменения, например, удалил обратные кавычки (которые порождают еще один подпроцесс в Perl и вызывают echo
) и вместо этого использую f-строки.
Кажется, это печатает все аргументы, как и ожидалось.
› python main.py
--channel
MyChannel
--userid
itsme
--message
Hello <at>[email protected]<at> : The ticket <a href = "http://snview/INC23548">INC23548</a> is not closed for more than 72 hours : Open since 14-APR-2024 12:30:40 IST. Please close asap.
Спасибо за ваш ответ. Я попробовал это первым, так как это выглядит очень аккуратно, однако возникла ошибка: «Использование неинициализированного значения $channel в конкатенации (.) или строки в /home/path/MyPerlScript.pl». Не уверен, что я делаю неправильно – возможно, что-то связано с тем, как написан Perl-скрипт. Если я печатаю cmd внутри Python, он просто печатает список.
Во-первых: вам не нужен echo
в Python, потому что вы помещаете непосредственно значения, а не переменные оболочки.
Во-вторых: поскольку сообщение находится в ' '
, внутри этого сообщения вам нужно использовать \'
, чтобы правильно его отформатировать.
Но для shell
было бы лучше разместить ссылку " "
внутри сообщения, которое находится в ' '
- '..."..."...'
- и поскольку вся строка находится в " "
, поэтому внутри строки вам понадобится \"
лайк " '...\"...\"...' "
f" ... --message 'Hello <at>{Mail}<at> : The ticket <a href=\"http://snview/{Ticket_Num}\">{Ticket_Num}</a> is not closed for more than 72 hours : Open since {Open_DtTime} IST. Please close asap.'"
Или вы должны вставить сообщение " "
и внутри сообщения использовать ' '
- - "...'...'..."
- и снова нужно \"
, но в другом месте
лайк " \"...'...'...\" "
f" ... --message \"Hello <at>{Mail}<at> : The ticket <a href='http://snview/{Ticket_Num}'>{Ticket_Num}</a> is not closed for more than 72 hours : Open since {Open_DtTime} IST. Please close asap.\""
Полный код для теста:
import subprocess
Mail = "[email protected]"
Ticket_Num = "INC23548"
Open_DtTime = "14-APR-2024 12:30:40"
cmd = f"./MyPerlScript.pl \
--channel 'MyChannel' \
--userid 'itsme' \
--message 'Hello <at>{Mail}<at> : The ticket <a href=\"http://snview/{Ticket_Num}\">{Ticket_Num}</a> is not closed for more than 72 hours : Open since {Open_DtTime} IST. Please close asap.'"
print(cmd)
subprocess.Popen(cmd, shell= True)#, stout=subprocess.PIPE)
Я согласен, что использование Echo или обратного тика никогда не было хорошей идеей - сначала я использовал строку формата - она не работала из-за неправильных escape-символов, на которые вы указали. Я погуглил и нашел где-то - так что просто попробовал. Мне помогло не первое решение (поскольку сообщение все еще приходило в одинарных кавычках), а второе решение. f" ... --message \"Привет <at>{Mail><at> : Заявка <a href='snview{Ticket_Num}'>{Ticket_Num}</a> не закрыта более чем 72 часа: открыто с {Open_DtTime} IST. Пожалуйста, закройте как можно скорее.»» Большое спасибо!
Я менял кавычки в ответе - возможно, вы пробовали старую версию :)
Нет, нет, я имел в виду, что вариант 1, указанный ниже, у меня не сработал : f" ... --message 'Hello <at>{Mail}<at> : Билет <a href=\"snview{ Ticket_Num}\">{Ticket_Num</a> не закрыт более 72 часов: открыт с {Open_DtTime} IST. Пожалуйста, закройте как можно скорее.'" Вариант 2 сработал.
Чтобы прояснить, как должна выглядеть ожидаемая команда, можете ли вы показать, как можно вызвать сценарий Perl из командной строки? Это может помочь нам понять, чего вы пытаетесь достичь с помощью сценария Python.