shell 用作 ssh 输入的 here-document 中的脚本没有给出任何结果

shell script in a here-document used as input to ssh gives no result

我将 grep 的结果通过管道传输到 AWK,并将结果用作 EOF 内另一个 grep 的模式(不确定那里的术语是什么),但 AWK 给我空白结果。以下是给我带来问题的 bash 脚本的一部分。

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

我真的在这里画了一个空白,因为没有错误而且我没有想法。

样本:

我正在 greping 如下所示的日志文件:

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*

locenvdate 工作正常,但它们在 EOF 之外。

整个脚本连接到 ssh 并正常退出,但我没有得到任何结果。

能否请您尝试以下。公平警告,由于缺少样品,我无法对其进行测试。通过这种方法,我们在执行 ssh 时不需要逃避。

##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  "::" }' | awk -F"," '{print }' | sort | uniq | while read -r rid ; do
zgrep "$rid $var_loc$var_env/app*$date*";
done
EOF

直接的问题是美元符号是由本地 shell 评估的,因为您没有(并且可能不能)引用此处的文档(因为那时 $wqr$loc 等也不会被 shell).

扩展

快速解决方法是反斜杠美元符号,但除此之外,我还看到了几个摆脱不雅或浪费结构的机会。

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 循环;但当然,您也需要在其中转义美元符号:

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 命令开始执行之前,任何未转义的美元符号都会由您的 local shell 求值。