skip to Main Content

Within a python script I have a function which looks as below:

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)

What it prints :

/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.' 

This command does not get executed successfully in the shell primarily because the message (all that is passed after ‘–message’ is within single quotes) or at least that is what is I think.
When I put that under double quotes python script throws syntax error.
When I put the whole cmd value in either single quote or doc string quote(”’) and –message content in double quote that results in syntax error as well.

If I run below cmd directly on the Linux command line (with the –message content within double quotes) it works fine:

> 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."

Now my question is how can I pass on this whole cmd value to subprocess so that the content of ‘–message’ can be rendered correctly – or how can I put the ‘–message’ content within double quotes and make it work.

Please note if I pass on the cmd as below – it works fine but it does not have the hyperlink for the ticket number. But I need the hyperlink.

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.' "

I have also tried putting the variables within {} and have tried various quote combinations. Nothing works so far.
I am using python 3.10

2

Answers


  1. subprocess.Popen takes a list as first argument which makes it easier to handle and interpolate strings. Instead of having to escape some sequences because others contain quotes or double quotes, split them up like in the examples from the docs.

    I created a test perl script that just prints each argument to run from python.

    #!/usr/bin/env perl
    
    use feature qw(say);
    
    say for @ARGV;
    

    And executing it from python like so

    #!/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")
    

    Note that I set shell to False and changed stdout to test your example so I can see what it prints. I also made some other changes like removing backticks (which will spawn yet another subprocess in perl and call echo) and use f-strings instead.

    This seems to print all the arguments as expected

    › python main.py
    --channel
    MyChannel
    --userid
    itsme
    --message
    Hello <at>[email protected]<at> : The ticket <a href="http://snview/fINC23548">INC23548</a> is not closed for more than 72 hours : Open since 14-APR-2024 12:30:40 IST. Please close asap.
    
    Login or Signup to reply.
  2. First: you don’t need echo in Python because you put directly values, not shell variables.

    Second: because message is in ' ' so inside this message you have to use ' to correctly format it.

    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.'"
    

    Full code for test:

    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)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search