J.Wang
J.Wang

Reputation: 1241

How to pass escape characters as command line parameters using python

I wrote a python script needed 2 command line arguments, and there are some '&'s in the 2nd parameter. And I received the error zsh parse error near &', so I tried to quoted and double-quoted these 2 parameters but the result went wrong. The code is simplified as below:

import base64, hmac, urllib, sys  
from hashlib import sha256  
def signature(secret_access_key, string_to_sign):  
    h = hmac.new(secret_access_key, digestmod=sha256)
    h.update(string_to_sign)
    sign = base64.b64encode(h.digest()).strip()  
    return urllib.quote_plus(sign)  
if __name__ == '__main__':  
    secret_access_key = 'a'  
    string_to_sign = 'b\nc\nd&e&f'  
    print signature(secret_access_key, string_to_sign)  
    print signature(sys.argv[1], sys.argv[2])  
    print sys.argv[2] == string_to_sign  

and following is the configuration in pycharm
enter image description here
print sys.argv[2] == string_to_sign returned False and
The result of signature(secret_access_key, string_to_sign) is what I expected, but I need to pass these 2 parameters in command line.
So is there any way to escape '&' and '\n' in command line?

Upvotes: 0

Views: 6749

Answers (2)

Alex
Alex

Reputation: 21766

You need to put quotes around your input parameters:

python yourscript.py "a" "b\nc\nd\&ef"

and change your script to replace the string "\n" with a carriage return:

import base64, hmac, urllib, sys  
from hashlib import sha256  
def signature(secret_access_key, string_to_sign):  
    h = hmac.new(secret_access_key, digestmod=sha256)
    h.update(string_to_sign)
    sign = base64.b64encode(h.digest()).strip()  
    return urllib.quote_plus(sign)  
if __name__ == '__main__':  
    secret_access_key = 'a'  
    string_to_sign = 'b\nc\nd&e&f'    
    input_argument = sys.argv[2].replace(r'\n','\n')
    print signature(secret_access_key, string_to_sign)  
    print signature(sys.argv[1], input_argument)      
    print input_argument == string_to_sign  

This gives as output:

iF5JXP343nGyFhcagBhVDVDSnECQpHDMnuq%2F6ryFzBc%3D
iF5JXP343nGyFhcagBhVDVDSnECQpHDMnuq%2F6ryFzBc%3D
True

Upvotes: 2

jfs
jfs

Reputation: 414885

If you want to include literal newlines; you could use $'' in bash, zsh:

$ python -c'import sys; print(sys.argv)' a $'b\nc\nd&e&f'
['-c', 'a', 'b\nc\nd&e&f']

If you want two characters: backslash + n then drop $:

$ python -c'import sys; print(sys.argv)' a 'b\nc\nd&e&f'
['-c', 'a', 'b\\nc\\nd&e&f']

Upvotes: 1

Related Questions