Получение последнего предложения беговой программы из STDOUT / STDERR

Согласно комментарию Стефана Чазеласа , проблема не в том, что пробел интерпретируется как новая строка. Он объяснил это в другом месте в связи с (концептуальным) оператором «split + glob», и хотя я не полностью следую его семантике, вот что происходит:

  • Переменная без кавычек разделяется на пробеле оболочкой, и они передаются в качестве аргументов в echo . Разделение удаляет пробелы.Это может немного сбивать с толку, так как «обратная косая черта-новая строка» кажется escape-последовательностью, но это НЕ эквивалентно x = \\\ n , это эквивалентно x = $ '\\ \ 012 ', \ 012 является восьмеричным для фактического перевода строки - в отличие от escape-последовательности \\ n , которая приводит к строке, содержащей литерал "\ n "(обратная косая черта-n), которая не будет разделена.

  • echo затем выводит свои аргументы, разделенные пробелом.

Повторим:

str1=hello\\nworld
str2=$'hello\012world'

Оболочка не будет разделять первую оболочку без кавычек, поскольку она фактически не содержит пробелов - она ​​содержит escape-последовательность \ n , тогда как во втором случае она будет быть разделенным без кавычек на фактическом символе новой строки (который является пробелом).

1
05.01.2019, 19:31
4 ответа

Поскольку qemu — это долго работающая программа, и она не возвращается к подсказке, проще открыть другой терминал и проверить, :какой IP-ПОРТ использует qemu. Итак, команда

$ netstat -tulpn | grep qemu-system | awk '{print $4}'
127.0.0.1:5900

Спасибо за предложения.

1
27.01.2020, 23:42

Я бы использовал tailи sedили простоsed

напр.

address=$(the_above_command | sed -r -e 's/VNC server running on ([0-9.:]+)$/\1/')
echo "$address" #or some other command

Проверьте бит в (), чтобы убедиться, что он дает то, что вы хотите. $(cmd)является подстановкой, она берет стандартный вывод cmdи заменяет себя этим выводом. Затем строка повторно -анализируется.

Примечание. :Если программа запущена/продолжает выполняться, вы не можете знать, является ли текущая строка последней строкой. К счастью, я не думаю, что вам нужно знать, что это последняя строка.

0
27.01.2020, 23:42

Здесь было бы полезно использовать комбинацию grepи cut.

Вы можете извлечь последнюю строку с помощью

grep -m1 'VNC server running on'

Флаг -m1будет означать, что grep прекратит чтение после первого совпадения, так как это предположительно длительный процесс.

Затем вы можете вырезать адрес с помощью

cut -d' ' -f5

Если вы хотите направить вывод в другой процесс, вы, вероятно, захотите запустить qemuв фоновом режиме следующим образом:

(qemu-system-x86_64... &) | grep -m1 'VNC server running on' | cut -d' ' -f5
0
27.01.2020, 23:42

Это должно работать:

grep -m1 -oP '(\d{1,3}\.?){4}:\d{1,5}' <( your-qemu-command 2>&1 )
  • <( your-qemu-command 2>&1 )— это замена процесса, которая запускает qemuс перенаправлением stdout/stderr в анонимный канал или FIFO;
  • grepчитает из канала/FIFO, грубо ища шаблон IP :PORT, где IP относится к IPv4-адресу.Параметр -oдля grepгарантирует, что будет напечатана только комбинация IP :PORT совпадающей строки; опция -m1гарантирует, что grepвернется к подсказке после того, как найдет то, что искал (, т. е. выйдет при первом совпадении ). Параметр -Pуказывает на использование синтаксиса регулярных выражений Perl.
  • обратите внимание, что qemuпродолжает работать в фоновом режиме, пока не завершится. Любой вывод на stdout/stderr с помощью qemuпосле завершения команды grepтеряется, но, поскольку предполагается, что комбинация IP :PORT является последним выводом, это не должно вызывать беспокойства.

Если вы хотите захватить вывод вышеуказанной команды, просто оберните его подстановкой команды $(...)вот так:

ip_port=$( grep...etc )
0
27.01.2020, 23:42

Теги

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