【问题标题】:shell script in a here-document used as input to ssh gives no result用作 ssh 输入的 here-document 中的 shell 脚本没有给出任何结果
【发布时间】:2020-01-10 11:28:56
【问题描述】:

我将 grep 的结果传递给 AWK,并将结果用作 EOF 中另一个 grep 的模式(不确定那里的术语是什么),但 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

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

样品:

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

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 并正常退出,但我没有得到任何结果。

【问题讨论】:

  • 没有看到输入和预期输出的样本,很难完全得到需求,所以请在你的帖子中添加样本,然后让我们知道。
  • @RavinderSingh13 添加了更多信息,如果需要更多信息,请告诉我。
  • 恕我直言,我们可以做些什么来解决这些问题:第一步-准备在目标服务器上运行的命令(从实际日志所属的位置),一旦完成第二步-使用需要对每个 ssh 进行更改才能从 ssh 运行它。现在让我们开始第一步-首先在目标服务器本身上准备命令,因为我们需要知道您需要什么示例输出,所以请更清楚。
  • @RavinderSingh13 原始命令在 ssh 服务器 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*; 上按预期工作。当然想像wgrloc 被更改为propper 值。但是 ssh 服务器需要进行哪些更改?
  • 我认为你需要逃避 $5 和 $7

标签: shell awk ssh grep eof


【解决方案1】:

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

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

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 也会评估任何未转义的美元符号。

【讨论】:

  • 尝试运行时出现以下错误:awk: cmd. line:1: {v = $5 "::" $7; split(v, f, /,/) print f[1]}awk: cmd. line:1: {v = $5 "::" $7; split(v, f, /,/) print f[1]} awk: cmd. line:1: ^ syntax error awk: cmd. line:1: ^ syntax error
  • 很抱歉,如果没有设置克隆,就无法真正测试它;但我添加了缺少的分号。感谢您的耐心等待。
  • sort之后尝试tee /dev/stderr |;但这不是便携式的。 xargs -t 提供的有用输出较少,而且 IIRC 也不完全可移植。
  • 这实际上就是它的作用,尽管由于缓冲的原因,在实践中排序可能会不稳定。我认为这是一项功能,但您显然可以将更复杂的内容传递给 xargs,例如 xargs sh -c 'for rid; do echo coloring noise "\$rid"; zgrep "\$rid" "$loc$env"/app*"$date"*; done' _(此处引用非常脆弱;希望我至少大致正确)。
  • 因为你也需要反斜杠那个美元符号。立即查看更新。
【解决方案2】:

请您尝试以下操作。公平的警告,由于缺少样品,我无法对其进行测试。通过这种方法,我们不需要在使用 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 $5 "::" $7}' | awk -F"," '{print $1}' | sort | uniq | while read -r rid ; do
zgrep "$rid $var_loc$var_env/app*$date*";
done
EOF

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-26
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多