Przepuszczenie dodatkowego stdio (nr. 3) przez dockera

0

Hej,
Potrzebuję w swoim projekcie wrzucić dodatkowy strumień stdio.
Dla przejrzystości, przygotowałem przykład:

app.c

#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[]){
        char buf[] = "Win!\n";
        (void)write(3, buf, strlen(buf));
        return 0;
}

Program ten wypisuje tekst nie na stdout(1), nie na stderr(2), tylko na deskryptor nr. 3.
Przykład:

$ gcc -o app app.c
$ ./app
$ ./app 3>&1
Win!

Potrzebuję teraz taki program odpalić przez dockera

Dockerfile

# docker build -t test .
# docker run -i test

FROM debian:stretch
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get -y install build-essential

WORKDIR /home

COPY app.c ./
RUN gcc -o app app.c
ENTRYPOINT ["./app"]

Po zbudowaniu docker build -t test . i odpaleniu:

$ docker run -i test
$ docker run -i test 3>&1

Niestety cisza.

Co muszę dodać do dockerfila, czy do argumentów dockera, aby ten przekazywał strumień?
Wszystkie pozostałe strumienie (stdin, stdout, stderr) działają, a ten nie :(

$ docker --version
Docker version 18.06.1-ce, build e68fc7a
1

Przekierowanie musisz zrobić wewnątrz kontenera, inaczej nic nie zobaczysz, bo Docker wyrzuca z siebie tylko i wyłącznie stdout, chyba, że dasz -i i wtedy również przyjmuje stdin. Więc by Twój program zadziałał musisz to zrobić w postaci sh -c 'test args 3>&1'. Aby to uzyskać możesz napisać coś takiego:

# docker build -t test .
# docker run -i test

FROM debian:stretch
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get -y install build-essential

WORKDIR /home

COPY app.c ./
RUN gcc -o app app.c
ENTRYPOINT ["/bin/sh", "-c", "./app \"[email protected]\" 3>&1", "--"]
0

Dzięki, jednak potrzebowałem dodatkowego deskryptora, aby odseparować dane stdin, stdout, stderr od komunikatów w jsonie.
Stworzyłem 2 dodatkowe programy, jeden po stronie hosta, a drugi po stronie dockera, które przesyłają przez stdin/stdout dockera wszystkie dane z deksryptorów z informacją z którego deskryptora są.

0

A nie myślałeś by użyć jakiegoś protokołu wymiany danych? Np. opakować je jakoś, wysłać socketem zamiast bawić się z kanałami? Ew. użyć Unix-socket?

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0