Каждый док-контейнер напрямую представляет только оболочку?

Учитывая file.html :


  
    link text 1
    link text 2
    link text 3
    ...
  

Мы можем использовать каналы Unix для отправки существующего вывода xmllint , в sed и увидим следующий результат:

$ xmllint --html --xpath //a/@href input.html | sed 's/ href="\([^"]*\)"/\1\n/g'
url1
url2
url3

Объяснение

Используя только xmllint , мы получаем только:

$ xmllint --html --xpath //a/@href input.html
 href="url1" href="url2" href="url3"%
  • завершающий % указывает, что нет завершающей новой строки

Одним из преимуществ Unix-подобных систем является то, что мы можем извлечь выгоду из функции каналов Дуга Макилроя , так что нам не нужно, чтобы одна программа пыталась сделать все, мы фактически рекомендуется комбинировать программы в соответствии с нашими потребностями.

Итак, найдя вывод xmllint неудовлетворительным, мы объединяем его по конвейеру с нашей командой sed , которая:

  • ищет href = "URL" единиц
  • с использованием группировки \ ( \) для окружения части URL
  • и замены ее на \ 1 \ n , чтобы она ссылалась на группу, которую мы определили вокруг URL-адреса, добавляя при этом новую строку после совпадения \ 1

Таким образом мы объединяем xmllint и sed для получения желаемого вывода с разделителями строк, по одному URL в строке.

1
07.04.2019, 01:50
1 ответ

То, как выполняется контейнер, зависит от того, как он был создан. В билдере Dockerfileмогут быть варианты CMDи ENTRYPOINT.

Например, вот контейнер, который никогда не вызывает /bin/sh.

Во-первых, программа, которую мы хотим запустить. Я написал это в goтолько потому, что это легко продемонстрировать.

$ cat small.go 
package main

import "fmt"
import "os"

func main() {
  fmt.Println("Hello")
  fmt.Print("You entered ")
  fmt.Println(os.Args[1:])
}

$ go build small.go

Теперь инструкция по сборке контейнера:

$ cat Dockerfile 
FROM scratch
ADD small /
ENTRYPOINT ["/small"]

$ docker build -t small.
Sending build context to Docker daemon  1.642MB
Step 1/3 : FROM scratch
 ---> 
Step 2/3 : ADD small /
 ---> Using cache
 ---> 6171cecbf91b
Step 3/3 : ENTRYPOINT ["/small"]
 ---> Using cache
 ---> 14af8187a035
Successfully built 14af8187a035
Successfully tagged small:latest

А теперь запускаем контейнер:

$ docker run --rm small some options passed
Hello
You entered [some options passed]

На самом деле этот контейнер содержит только один файл, программу smallи больше ничего! Ни оболочки, ни библиотек, ничего.

Теперь образ докера, на который вы смотрите, попадет в python, если вы запустите его правильно и не передадите никаких параметров

$ docker run --rm -it python:2.7-slim
Python 2.7.16 (default, Mar 27 2019, 09:57:44) 
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

Если мы посмотрим на изображение, то увидим...

$ docker inspect python:2.7-slim
...
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"python2\"]"
            ],

Итак, мы видим, что он был построен с опцией CMDв Dockerfile. Это говорит ему, что команда по умолчанию должна выполняться, если никакая другая команда не передается вызову docker run.

Таким образом, с этим контейнером он будет работать python, если ему не будет предложено запустить что-либо еще.

Это означает, что мы можем делать такие забавные вещи, как

$ echo 'print("hello")' | docker run --rm -i python:2.7-slim
hello
3
27.01.2020, 23:22

Теги

Похожие вопросы