简体   繁体   中英

subprocess.run failing to run command

I pass this string to subproccess.run and split on spaces.

This is how I build the string

patch_request = f"""/usr/local/bin/kubectl patch secret {secret_name} --type="json" -p='[{{"op":"replace","path":"/data/{k}","value":"{v}"}}]'"""

It produces

/usr/local/bin/kubectl patch secret beta --type="json" -p=\'[{"op":"replace","path":"/data/foo","value":"mock_value"}]\'

I end up getting this error back. Any idea what could be going wrong?

CompletedProcess(args=['/usr/local/bin/kubectl', 'patch', 'secret', 'beta', '--type="json"', '-p=\'[{"op":"replace","path":"/data/foo","value":"mock_value"}]\''], returncode=1, stdout='', stderr='error: --type must be one of [json merge strategic], not "\\"json\\""\n')

Building up the command as an array to send to subprocess.run instead of doing a string substitution is slightly more work at first but gives much greater flexibility later when args and options need to be conditionally added, changed, etc. I would set it up this way:

    secret_name = "foo"
    k = 'K1'
    v = 'Dragon\'s "lair"'

    print(v)  # This will come out as  Dragon's "lair"  Note no backslash

    # Set up the baseline command that does not change a lot:                                                         
    cmd = ['/usr/local/bin/kubectl','patch','secret',secret_name,'--type=json']                                      
    
    #  Set up the more variable bits as a regular dict, not JSON. This gives
    #  you great control over setting up the data without worrying about
    #  formatting it into the final JSON representation:                                                    
    parg = {"op":"replace", "path":"/data/%s" % k, "value":v}

    #  Now, "at the end", turn the more complex args into JSON.  This will, among                                     
    #  other things, take care of args that themselves contain single and double                                      
    #  quotes and other chars that complicate rendering to JSON:                                                      
    cmd.append("-p=%s" % json.dumps(parg))

    #  Run subprocess as a cmd array, not through the shell:                                                          
    p1 = subprocess.run(cmd, text=True, capture_output=True)
    print(p1.stdout)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM