Ручной наблюдатель за папками для трансмиссии?

Для тех, кто не понимает advanced awk , а также хотел бы (например, для таких, как я) и не имеет предустановленного jq , простым решением было бы объединение нескольких собственных команд, таких как:

grep -A2 '"id": 1490,' stats.json | sed '/1490/d;s/"//g;s/,//;s/\s*//'

Если вы пытаетесь получить только значения, проще просто использовать grep , а не awk или sed :

grep -A2 '"id": 1490,' stats.json | grep -o "[0-9]*\.[0-9]*"

Чтобы дать объяснение, это кажется мне самым простым способом.

  • В grep -A2 захватов линия, которую вы ищете в JSON, вместе со следующими линиями 2, которые содержат температуру и влажность.
  • Труба в grep -o просто печатает только цифры, разделенные . (что никогда не произойдет на первой 1490 линии, поэтому вы оставлены с вашими 2 значениями - температура и влажность. Очень просто. Даже проще, чем использовать jq , на мой взгляд.

-121--32291-

Существуют два очевидных способа представления вывода столбчатых данных в JSON: массив массивов и массив объектов. В первом случае каждая строка ввода преобразуется в массив; в последнем - к объекту.

Перечисленные ниже команды работают, по крайней мере, с выходом procps-ng в Linux для команд ps и ps -l .

Параметр # 1: массив массивов

С помощью Perl

можно преобразовать выходные данные с помощью Perl и модуля CPAN JSON:: XS .

# ps | perl -MJSON -lane 'my @a = @F; push @data, \@a; END { print encode_json \@data }'
[["PID","TTY","TIME","CMD"],["12921","pts/2","00:00:00","ps"],["12922","pts/2","00:00:00","perl"],["28280","pts/2","00:00:01","zsh"]]

С помощью jq

можно также использовать jq для преобразования.

# ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]' 
[
  [
    "PID",
    "TTY",
    "TIME",
    "CMD"
  ],
  [
    "16694",
    "pts/2",
    "00:00:00",
    "ps"
  ],
  [
    "16695",
    "pts/2",
    "00:00:00",
    "jq"
  ],
  [
    "28280",
    "pts/2",
    "00:00:02",
    "zsh"
  ]
]

Параметр # 2: массив объектов

Можно преобразовать входные данные в массив объектов JSON с значимо именованными ключами, взяв имена ключей из строки заголовка.

Это требует немного больше усилий и немного сложнее в jq в частности. Однако результат, возможно, более удобочитаем для человека.

Использование Perl

# ps | perl -MJSON -lane 'if (!@keys) { @keys = @F } else { my %h = map {($keys[$_], $F[$_])} 0..$#keys; push @data, \%h } END { print encode_json \@data }'
[{"TTY":"pts/2","CMD":"ps","TIME":"00:00:00","PID":"11030"},{"CMD":"perl","TIME":"00:00:00","PID":"11031","TTY":"pts/2"},{"TTY":"pts/2","CMD":"zsh","TIME":"00:00:01","PID":"28280"}]

Обратите внимание, что ключи находятся в произвольном порядке для каждой записи. Это артефакт того, как работают хэши Перла.

Использование jq

# ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]] | .[0] as $header | .[1:] | [.[] | [. as $x | range($header | length) | {"key": $header[.], "value": $x[.]}] | from_entries]'
[
  {
    "PID": "19978",
    "TTY": "pts/2",
    "TIME": "00:00:00",
    "CMD": "ps"
  },
  {
    "PID": "19979",
    "TTY": "pts/2",
    "TIME": "00:00:00",
    "CMD": "jq"
  },
  {
    "PID": "28280",
    "TTY": "pts/2",
    "TIME": "00:00:02",
    "CMD": "zsh"
  }
]

-121--78913-

Зачем изобретать колесо заново? qprint уже существует:

Description-en: encoder и decoder для кодировки с печатью в кавычках

Qprint - это программа командной строки, которая может кодировать или декодировать файлы кодирование с печатью в кавычках (RFC1521). Он может работать с обоими текстовые и двоичные данные.

Домашняя страница: http://www.fourmilab.ch/webtools/qprint/

Пример ввода:

$ cat nadir.txt 

Hyundai ya ofrece manuales de = los coches con Realidad Aumentada

Пример вывода:

$ qprint -d nadir.txt 

Hyundai ya ofrece manuales de los coches con Realidad Aumentada

qprint предварительно упакован для большинства distros linux.

Есть также несколько модулей жемчуга для кодирования & указанной расшифровки - пригодный для печатания текст, включая ПАНТОМИМА:: QuotedPrint и PerlIO:: через:: QuotedPrint. Несомненно, быстрый поиск Google также выявит библиотеки QP для питона и других языков.

4
11.07.2018, 08:29
3 ответа

Спасибо всем. И дело в разделителе. Я меняю "/" на ":" и все работает. Выкладываю результат сюда. В «Шаге 65/78» я печатаю содержимое сценария, а «Шаг 67/78» хорошо запускает сценарий. Спасибо @xenoid и @Kusalananda.

Step 63/78 : RUN echo "#!/bin/sh -x\nsed -i 's:PRIVATEIP:'"$(cat /home/ip_variable)"':g' /etc/fail2ban/jail.local\nsed -i 's:PRIVATEIP:'"$(cat /home/ip_variable)"':g' /etc/opendkim/TrustedHosts" > /home/ip_change_script.sh
 ---> Running in 251d6741c37e
Removing intermediate container 251d6741c37e
 ---> 95c4aa62d74a
Step 64/78 : RUN cat /home/ip_variable
 ---> Running in 8825ef517fb8
172.17.0.2/16
Removing intermediate container 8825ef517fb8
 ---> 39672eb7021d
Step 65/78 : RUN cat /home/ip_change_script.sh
 ---> Running in 2161051ee4cf
#!/bin/sh -x
sed -i 's:PRIVATEIP:'172.17.0.2/16':g' /etc/fail2ban/jail.local
sed -i 's:PRIVATEIP:'172.17.0.2/16':g' /etc/opendkim/TrustedHosts
Removing intermediate container 2161051ee4cf
 ---> 407ccc7106f7
Step 66/78 : RUN chmod 755 /home/ip_change_script.sh
 ---> Running in 0f6ca7f78ba8
Removing intermediate container 0f6ca7f78ba8
 ---> 250afb327db0
Step 67/78 : RUN sh /home/ip_change_script.sh
 ---> Running in 4b209e18854b
Removing intermediate container 4b209e18854b
 ---> d45d024e1359
Step 68/78 : RUN touch /home/service_boot.log
 ---> Running in 3548dc45f466
Removing intermediate container 3548dc45f466
 ---> 587527e18ab2
Step 69/78 : RUN cat /home/service_boot.log
 ---> Running in b068b00cd584
Removing intermediate container b068b00cd584
 ---> 3183e6b281ed
Step 70/78 : COPY boot_service.sh /home/boot_service.sh
 ---> 9a73dd4fd87d
Step 71/78 : RUN chmod 755 /home/boot_service.sh
 ---> Running in 2f226574e28d
Removing intermediate container 2f226574e28d
 ---> 8a0c14218e1b
Step 72/78 : RUN cat /home/boot_service.sh
 ---> Running in 5fa64827b6dd
4
27.01.2020, 20:48

Присваивание не производит вывода, поэтому бессмысленно передавать его другому процессу.

Вместо этого используйте ;, чтобы разделить конвейер на две последовательные команды:

IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local

Я не знаком с Docker и его командой RUN. Если требуется только одна команда , используйте

.
RUN sh -c 'IP=$(cat /root/ip_variable); sed -i "s/PRIVATEIP/$IP/g" /etc/fail2ban/jail.local'

или

RUN sed -i "s/PRIVATEIP/$(cat /root/ip_variable)/g" /etc/fail2ban/jail.local
2
27.01.2020, 20:48

Это работает для меня:

FROM alpine

COPY ipaddr /ipaddr
COPY ipconf /ipconf
RUN export IPADDR=$(cat /ipaddr) ; sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf

С ipconf и ipaddr

IP address is IPADDR

1.2.3.4

Тогда:

>docker build -t dynchange.
Sending build context to Docker daemon   5.12kB
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY ipaddr /ipaddr
---> Using cache
---> 1828c3157d41
Step 3/5 : COPY ipconf /ipconf
---> 4f43e88e4425
Step 4/5 : RUN export IPADDR=$(cat /ipaddr) ;  sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
---> Running in 722c3d3d9d9e
Removing intermediate container 722c3d3d9d9e
---> 32e31198b70a
Step 5/5 : CMD cat /ipconf
---> Running in 72ea59543a7f
Removing intermediate container 72ea59543a7f
---> 73f8a50d650a
Successfully built 73f8a50d650a
Successfully tagged dynchange:latest

>docker run --rm dynchange
IP address is 1.2.3.4

Однако именно так я бы не поступил. Лучше использовать аргумент сборки:

FROM alpine

COPY ipconf /ipconf
ARG IPADDR
RUN sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
CMD cat /ipconf

Тогда:

>docker build -t dynchange --build-arg IPADDR=4.5.6.7 .
Sending build context to Docker daemon   5.12kB
Step 1/5 : FROM alpine
---> 3fd9065eaf02
Step 2/5 : COPY ipconf /ipconf
---> Using cache
---> f5ac88ee48d5
Step 3/5 : ARG IPADDR
---> Running in 58d972e14660
Removing intermediate container 58d972e14660
---> fc3de48160c6
Step 4/5 : RUN sed -i -r "s/IPADDR/${IPADDR}/g" /ipconf
---> Running in 8ec855697510
Removing intermediate container 8ec855697510
---> 67e946559316
Step 5/5 : CMD cat /ipconf
---> Running in a5260c593c02
Removing intermediate container a5260c593c02
---> 567a31a517d1
Successfully built 567a31a517d1
Successfully tagged dynchange:latest

>docker run --rm dynchange
IP address is 4.5.6.7

Однако я даже не уверен, что это правильное решение. Я бы либо:

  • создайте файл конфигурации вне контейнера и создайте/замените его файлом COPY. Это дает полный контроль над его содержимым.
  • передать этот IP-адрес в качестве параметра при запуске контейнера (переменную среды или еще ), чтобы у вас был один образ контейнера, который можно использовать в нескольких средах. CMDили ENTRYPOINTмогут быть сценарием, который исправляет файл перед вызовом основной команды. Вы также можете передать файл конфигурации как VOLUME (. Это поможет избежать проблем, если CMD запускается от имени пользователя приложения, а для исправления конфигурации требуются привилегии root ).
5
27.01.2020, 20:48

Теги

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