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

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

提问人:Artur Albert Hamelak 提问时间:1/10/2020 最后编辑:RavinderSingh13Artur Albert Hamelak 更新时间:1/15/2020 访问量:209

问:

我正在将 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*

loc,并且工作正常,但它们不在 EOF 范围内。envdate

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

shell awk ssh grep eof

评论

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

答:

2赞 RavinderSingh13 1/10/2020 #1

你能试着关注一下吗?公平的警告,由于缺乏样本,我无法测试它。通过这种方法,我们不需要在做 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
3赞 tripleee 1/10/2020 #2

眼前的问题是美元符号是由本地 shell 评估的,因为您没有(并且可能不能)引用此处的文档(因为 then 和 etc 也不会被 shell 扩展)。$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

如果你想在决赛周围添加装饰,可能会恢复到你所拥有的循环;但是,当然,您也需要在其中转义美元符号:zgrepwhile

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

同样,甚至在命令开始执行之前,本地 shell 都会评估任何未转义的美元符号。ssh

评论

0赞 Artur Albert Hamelak 1/14/2020
尝试运行它时出现以下错误: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
1赞 tripleee 1/14/2020
很抱歉,如果不设置设置的克隆,就无法真正测试这一点;但我添加了缺少的分号。感谢您的耐心等待。
1赞 tripleee 1/14/2020
尝试之后 ;但这不是便携式的。 提供不太有用的输出,并且也不是完全可移植的 IIRC。tee /dev/stderr |sortxargs -t
1赞 tripleee 1/14/2020
这实际上就是它的作用,尽管由于缓冲,排序在实践中可能会不稳定。我认为这是一个功能,但你显然可以传递一些更复杂的东西,比如(那里的引用很脆弱;希望我至少大致正确)。xargsxargs sh -c 'for rid; do echo coloring noise "\$rid"; zgrep "\$rid" "$loc$env"/app*"$date"*; done' _
1赞 tripleee 1/15/2020
因为你也需要反切那个美元符号。刚才看到更新。