избежать проблемы с буферизацией bash при обработке журнала

Вы создаете временную HTML-страницу с автоматической -отправкой, указываете браузер на эту страницу и через пару секунд удаляете временный HTML-файл, так как он больше не нужен. В форме сценария:

#!/bin/bash

# Create an autodeleted temporary directory.
Work="$(mktemp -d)" || exit 1
trap "cd / ; rm -rf '$Work'" EXIT

# Create a HTML page with the POST data fields,
# and have it auto-submit when the page loads.
cat > "$Work/load.html" <<END
<!DOCTYPE html>
<html>
 <head>
  <title>&hellip;</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <script type="text/javascript">
   function dosubmit() { document.forms[0].submit(); }
  </script>
 </head>
 <body onload="dosubmit();">
  <form action="https://www.startpage.com/do/asearch" method="POST" accept-charset="utf-8">
   <input type="hidden" name="cat" value="web">
   <input type="hidden" name="cmd" value="process_search">
   <input type="hidden" name="language" value="english">
   <input type="hidden" name="engine0" value="v1all">
   <input type="hidden" name="query" value="&#34;Nominal Animal&#34;">
  </form>
 </body>
</html>
END

# Load the generated file in the browser.
firefox "file://$Work/load.html"

# Firefox returns immediately, so we want to give it a couple
# of seconds to actually read the page we generated,
# before we exit (and our page vanishes).
sleep 2

Давайте изменим приведенное выше, чтобы мы выполняли поиск StartPage по любой строке (s ), заданной в командной строке:

#!/bin/bash

# Create an autodeleted temporary directory.
Work="$(mktemp -d)" || exit 1
trap "cd / ; rm -rf '$Work'" EXIT

# Convert all command-line attributes to a single query,
# escaping the important characters.
rawAmp='&'   ; escAmp='&amp;'
rawLt='<'    ; escLt='&lt;'
rawGt='>'    ; escGt='&gt;'
rawQuote='"' ; escQuote='&#34;'
QUERY="$*"
QUERY="${QUERY//$rawAmp/$escAmp}"
QUERY="${QUERY//$rawQuote/$escQuote}"
QUERY="${QUERY//$rawLt/$escLt}"
QUERY="${QUERY//$rawGt/$escGt}"

# Create a HTML page with the POST data fields,
# and have it auto-submit when the page loads.
cat > "$Work/load.html" <<END
<!DOCTYPE html>
<html>
 <head>
  <title>&hellip;</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <script type="text/javascript">
   function dosubmit() { document.forms[0].submit(); }
  </script>
 </head>
 <body onload="dosubmit();">
  <form action="https://www.startpage.com/do/asearch" method="POST" accept-charset="utf-8">
   <input type="hidden" name="cat" value="web">
   <input type="hidden" name="cmd" value="process_search">
   <input type="hidden" name="language" value="english">
   <input type="hidden" name="engine0" value="v1all">
   <input type="hidden" name="query" value="$QUERY">
  </form>
 </body>
</html>
END

# Load the generated file in the browser.
firefox "file://$Work/load.html"

# Firefox returns immediately, so we want to give it a couple
# of seconds to actually read the page we generated,
# before we exit (and our page vanishes).
sleep 2

Все, что изменилось, — это фрагмент, в котором мы используем строковые операции Bash для замены каждого &на &amp;, каждого "на &#34;, каждого <на &lt;и каждого >на &gt;, чтобы строку запроса можно было безопасно записать как атрибут valueскрытого ввода с именем query. (Этих четырех достаточно. Также важно сначала поставить амперсанд, потому что последующие замены содержат амперсанд. Поскольку мы выдаем это как значение скрытого ввода, строка запроса не кодируется URL -; это обычный HTML-контент, но без двойных кавычек (, потому что само значение заключено в двойные кавычки ).)

Недостаток автоматической -отправки POST-запросов заключается в том, что вам может потребоваться время от времени обновлять HTML-страницу автоматической -отправки,просто потому, что сайт может изменить имя переменной POST и внутренние URL-адреса, когда захочет.

1
10.09.2019, 11:44
1 ответ

Я не уверен, что вы получите, используя <(...)вместо простого трубопровода:

journalctl... |
jq -r... |
while read LOG_FACILITY LOG_SEVERITY LOG_TAG LOG_MESSAGE
do logmessage...
done

Конечно, обе версии имеют одинаковую проблему с буферизацией.

Однако в любом случае, если вы хотите использовать socatдля запуска команды jq, вы можете сделать это, заменив jq -r...на

socat -u EXEC:'jq -r...',pty,ctty STDIO

, но есть большая проблема с необходимостью заключать аргументы jqв кавычки, так как socatнемного искажает их, и сложно правильно передать строку. Один из способов обойти это — сохранить команду в переменной оболочки, а затем использовать ее позже :

.
export cmd="$(cat <<\! 
jq -r '"\(.SYSLOG_FACILITY // 3) \(.PRIORITY // 6 ) \(.SYSLOG_IDENTIFIER // "journald") \(.MESSAGE | sub("\\n";" ";"g") // "no message")"'
!
)"

socat -u SYSTEM:'eval $cmd',pty,ctty STDIO

Но, наконец, ни в чем из этого не должно быть необходимости, так как jqпринимает вариант --unbuffered, который позволит достичь желаемого эффекта.

0
28.01.2020, 00:00

Теги

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