0

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?

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

5 Comments

I tried quoted and double-quoted these 2 parameters in CLI but the results are different, so is the result of print sys.argv[2], string_to_sign
Did you escape your string_to_sign value as well ?
There is no need to escape string_to_sign ,because non escape string_to_sign is exactly what I need.
But iF5JXP343nGyFhcagBhVDVDSnECQpHDMnuq%2F6ryFzBc%3D is the result I want. I can get this without escaping string_to_sign
In that case you need to quote your input parameter and replace the string \n with a carriage return, see updated answer
1

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']

1 Comment

This is the output I want. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.