In a shell session I have run:
docker run --rm --net host busybox /bin/sh -c "ip route get 1 | sed -n 's/^.*src ([0-9.]*) .*$/1/p'"
The output of the command is:
10.0.2.15
But for a utility script that interfaces docker directly using python and docker-sdk I run the same command as well:
import docker
client = docker.from_env()
print(client.containers.run('busybox',["/bin/sh","-c","ip route get 1 | sed -n 's/^.*src ([0-9.]*) .*$/1/p'"],remove=True,network="host"))
But I get the following output:
b'x01n'
I tried to convert into ascii like this:
print(client.containers.run('busybox',["/bin/sh","-c","ip route get 1 | sed -n 's/^.*src ([0-9.]*) .*$/1/p'"],remove=True,network="host").decode('ascii'))
But seem not to print any printable character despite spaces. Any idea how I can retrieve the same output using python?
Edit 1
I also tried to capture the stdout:
client.containers.run('busybox',["/bin/sh","-c","ip route get 1 | sed -n 's/^.*src ([0-9.]*) .*$/1/p'"],remove=True,network="host",stdout=True)
But same result occur.
Though if I ommit the sed part seems to work fine (but having the result not filtered):
print(client.containers.run('busybox',["/bin/sh","-c","ip route get 1"],remove=True,network="host"))
Prints:
b'1.0.0.0 via 10.0.2.2 dev enp0s3 src 10.0.2.15 n'
Therefore for some reason sed part seems to break the output.
2
Answers
The issue is caused by unescaped
1
atsed
part of the command. In order to work you must do:Pay attention on this string used as second argument for the functipon:
You can avoid the escaping problem you describe in your answer by post-processing the output in Python code. This also means you don’t need a shell in your container invocation, which removes a potential level of quoting (and attendant security concerns).
For this particular case, since you’re using the host network and then requesting network information, you’re seeing the host’s network setup. If your Docker environment is based on a virtual machine (for example, Docker Desktop) you’re seeing that VM’s network environment; this is not a portable path to find the host’s gateway address. If you’re on a native-Linux system you can often just run this command using the
subprocess
module without involving Docker (the decoding details are otherwise identical to what’s in this answer). Python: get default gateway for a local interface/ip address in linux has a number of other approaches that don’t require Docker.