0

I have a key value pair that I want to export from the bash script which the following python is embedded in. Excerpt from bash script:

output_test="ip:192.168.1.150,status:up"
export output_test

Embedded python within above bash script

python -c "$(cat << 'EOF'
import socket
import os
import json
bash_output=string(os.environ["output_test"])
sd = dict(u.split(":") for u in output_test.split(","))
print json.dumps(sd)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 15000))
s.send(bytes(json.dumps(s)))
result = json.loads(s.recv(1024))
print result
s.close()
EOF
)"

I'm quite new to Python I will admit I've hashed this together after intense speed research, and it's all I am going to need it to do in my scripts. Send name value pairs to a socket as a json array. Also, will the name I give the JSON object in the python, sd in the example above, become the name of the JSON array? - I will want to give it a meaningful name in the final version.

The error I'm getting is string not defined, which I think it means the string bash_output

1
  • 1
    There is no module called dictionary in standard python. You never assign a value to output_test, presumably you are missing output_test = os.environ['output_test']. No the name you assign the json will have no affect on the json ouput. Commented Apr 3, 2015 at 4:09

3 Answers 3

1

I agree with @achampion, output_test seems to be mixed up with bash_output. A quick fix would probably be:

bash_output=os.environ["output_test"]
sd = dict(u.split(":") for u in bash_output.split(","))

You may also consider just not using environment variable this way:

$ output_test="ip:192.168.1.150,status:up"
$ python -c "$(cat << 'EOF'
import socket
import os
import json
import sys
bash_output = sys.argv[1]
sd = dict(u.split(":") for u in bash_output.split(","))
print json.dumps(sd)
EOF
)" $output_test
{"status": "up", "ip": "192.168.1.150"}
Sign up to request clarification or add additional context in comments.

4 Comments

Unfortunately there's no builtin string in Python, so that quick fix is wrong.
Yep, sorry, forgot to remove the string(...) which is wrong too
Can anyone tell me why the following string is converting the commas to spaces and how I can correct it? Bash is doing this output="Name:plugin,Timestamp:${timestamp},UUID:b4238ca2-cb8d-11e4-8731-1681e6b88ec1,RecDays:${NC_recDays} I'm trying to use in a different plugin
Maybe there are some problematic characters in ${timestamp} or ${NC_recDays} that involve such a behavior, but it is difficult to answer without the expanded value of $output. Could you add an echo $output in your script and post the result please ?
0

You get NameError: name 'string' is not defined because, well, string is not defined. There's no Python builtin called string. os.environ["whatever"] already has type str, so you don't need any conversion.

Of course that's not the only problem. You assigned the env var to bash_output but later try to use the variable name output_test. Presumably that's a typo, so you also have to change that.

Everything corrected:

#!/usr/bin/env bash
output_test="ip:192.168.1.150,status:up"
export output_test
python -c "$(cat <<'EOF'
import socket
import os
import json
print(os.environ)
bash_output = os.environ['output_test']
sd = dict(u.split(":") for u in bash_output.split(","))
print json.dumps(sd)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 15000))
s.send(bytes(json.dumps(s)))
result = json.loads(s.recv(1024))
print result
s.close()
EOF
)"

Then I don't really know what your socket does (unless you provide more info), so you have to make sure that part is correct.

11 Comments

Now I see that @achampion's fix is essentially the same, though they didn't point out what the error message means.
FYI there is a string module, but it does something else entirely :)
@Joost Note that I said there's no Python builtin called string.
Thank you everyone. Really appreciated and I've gained some extra understanding of Python from you all too!
@user1556814 you're alternative feeding as an argument works fine.
|
0

This is the final code I have which is working, using @user1556814 solution:

output_test="ip:192.168.1.150,status:up"


python -c "$(cat << 'EOF'
import socket
import os
import json
import sys 
bash_output = sys.argv[1]
sd = dict(u.split(":") for u in bash_output.split(","))
print json.dumps(sd)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 15000))
s.send(bytes(json.dumps(sd)))
s.close()
EOF
)" $output_test

My question, forgive me, is it safe? It's going to be sending packets of data, perhaps up to 30, between programmes on a local machine. They will almost identical as the above, so very small, simple json objects, likely every 10 seconds. Just the one bash script running each time and outputting the above from the command it has run (with some awk in there too). As I don't know the language very well, I hope I haven't missed any gotchas? This code really simplifies what I want to do, and if it works, well, I can deepen my python knowledge later, when I have more time and less panic :)

2 Comments

If that's your use case, then yes, you should use argv instead of env var. And I would put the python code into a separate python script rather than putting it in a Bash script within an evil cat heredoc construct. And what do you mean by "safe"? For safety you should really quote $output_test (i.e., "$output_test"). And you might need better parsing than dict(u.split(":") for u in bash_output.split(",")), depending on the format of your strings. Other than that, it's safe as long as you can make sure there's no unwanted malicious access.
@4ae1e1 Yes I don't mean safe in the secure sense, but rather in the unwanted side effects sense. Or In the sense of not personally knowing much of what is going under the hood. Thanks for you tips. I will post up those other errors later when I have sec

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.