Скрипт оболочки в здесь-документе, используемый в качестве ввода для s sh, не дает результата - PullRequest
1 голос
/ 10 января 2020

Я передаю результат grep в AWK и использую результат в качестве шаблона для другого grep внутри EOF (не знаю, какая там терминология), но AWK дает мне пустые результаты. Ниже приведена часть скрипта bash, которая вызвала у меня проблемы.

ssh "$USER"@logs << EOF
  zgrep $wgr $loc$env/app*$date* | awk -F":" '{print $5 "::" $7}' | awk -F"," '{print $1}' | sort | uniq | while read -r rid ; do
  zgrep $rid $loc$env/app*$date*;
done
EOF

Я действительно рисую здесь пробел, потому что не ошибаюсь и у меня нет идей.

Образцы:

Я создаю grep-файлы журналов, которые выглядят следующим образом:

app-server.log.2020010416.gz:2020-01-04 16:00:00,441 INFO [redacted] (redacted) [rid:12345::12345-12345-12345-12345-12345,...

Я заинтересован в программе rid и могу снова выполнить grep в журналах:

zgrep $rid $loc$env/app*$date*

loc, env и date работают нормально, но находятся вне EOF.

Скрипт в целом подключается к s sh и работает нормально, но я не получаю никакого результата.

Ответы [ 2 ]

3 голосов
/ 10 января 2020

Непосредственная проблема заключается в том, что знаки доллара оцениваются локальной оболочкой, потому что вы не (и, вероятно, не можете) процитировать документ здесь (потому что тогда $wqr и $loc et c также не будут расширены оболочкой).

Быстрое решение проблемы с бэкслой sh знаков доллара, но, кроме того, я вижу несколько возможностей избавиться от не элегантных или расточительных конструкций.

ssh "$USER"@logs << EOF
  zgrep "$wgr" "$loc$env/app"*"$date"* |
  awk -F":" '{v = \$5 "::" \$7; split(v, f, /,/); print f[1]}' |
  sort -u | xargs -I {} zgrep {} "$loc$env"/app*"$date"*
EOF

Если вы хотите добавить украшения вокруг финального zgrep, возможно, вернитесь к while l oop, который у вас был; но, разумеется, в этом случае вам также нужно избегать знака доллара:

ssh "$USER"@logs << EOF
  zgrep "$wgr" "$loc$env/app"*"$date"* |
  awk -F":" '{v = \$5 "::" \$7; split(v, f, /,/); print f[1]}' |
  sort -u |
  while read -r rid; do
    echo Dancing hampsters "\$rid" more dancing hampsters    
    zgrep "\$rid" "$loc$env"/app*"$date"*
  done
EOF

Опять же, любой неэкранированный знак доллара оценивается вашей локальной оболочкой даже до команды ssh начинает выполнение.

2 голосов
/ 10 января 2020

Не могли бы вы попробовать следующее. Честное предупреждение, я не смог проверить это из-за отсутствия образцов. При таком подходе нам не нужно избегать вещей при выполнении s sh.

##Configure/define your shell variables(wgr, loc, env, date, rid) here.
printf -v var_wgr %q "$wgr"
printf -v var_loc %q "$loc"
printf -v var_env %q "$env"
printf -v var_date %q "$date"

ssh -T -p your_pass user@"$host" "bash -s $var_str" <<'EOF'

# retrieve it off the shell command line
zgrep "$var_wgr $var_loc$var_env/app*$var_date*" | awk -F":" '{print $5 "::" $7}' | awk -F"," '{print $1}' | sort | uniq | while read -r rid ; do
zgrep "$rid $var_loc$var_env/app*$date*";
done
EOF
...