【问题标题】:Executing pipe or for loop in bash -c over ssh in Jenkins pipeline在 Jenkins 管道中通过 ssh 在 bash -c 中执行管道或 for 循环
【发布时间】:2018-03-08 18:28:09
【问题描述】:

简介

我正在编写一个从 Jenkins Pipeline 执行的 bash 脚本。 Groovy DSL 对我来说不是问题,我使用的是裸 shell 命令。

到目前为止,对于每个命令,我一直在使用 bash -c 并传递了我想要的命令,如下所示:

ssh -l <user> <host> bash -c "'
     cd /my/path
     ./script.sh param1 param2
     echo $MY_VAR
'"

效果很好。


问题

现在我有一个更复杂的命令:

ls -1t | egrep 'regexp' | tail -n +10 | xargs rm -rf 

基本上列出一些目录并删除除最后 10 个以外的所有项目。它在 bash 中使用,但在 bash -c 中不起作用。

我也尝试了 for-loop 版本:

for f in $(ls -1t | egrep 'regexp' | tail -n +10); do rm -rf $f; done;

但它也不起作用。 我收到一个错误,例如:

bash: line 4:
  for f in <actual_item1> <actual_item2> <actual_item3>; do echo <actual_item1>; done;
       No such file or directory

所以$ 变量分辨率存在一些问题。如何克服这一点? 或者我如何使 piped 版本工作?

【问题讨论】:

  • edit 您的问题显示您正在运行的实际 ssh 命令,并且引号和变量引用完好无损。这可能只是让您的报价正确的问题。
  • 不是引号。 bash -c 在通过此管道时不起作用(我不知道为什么),但通过 &lt;&lt; EOF 会有所帮助。

标签: bash jenkins ssh jenkins-plugins jenkins-pipeline


【解决方案1】:

您可以使用 here-doc 和 ssh 命令来运行一个或多个命令:

ssh $user@$hostname bash -s<<-'EOF'
ls -1t | egrep 'regexp' | tail -n +10 | xargs rm -rf
EOF

但不建议解析ls 命令的输出,最好像这样使用find ... -print0

ssh $user@$hostname bash -s<<-'EOF'
find . -regex '.*regexp' -print0 | tail -zn +10 | xargs -0 rm -rf
EOF

【讨论】:

  • 这将使用我在服务器上的默认shell(ksh),所以我需要指定shell。
  • ok bash -s 应该注意这一点。立即尝试我的更新答案。
  • 你为什么要为此使用任何外壳? ssh $user@$hostname "find . -regex '.*regexp' -print0 | tail -zn +10 | xargs -0 rm -rf".
  • 是的@chepner,这些命令不需要bash。由于 OP 专门要求能够运行 bash,因此我假设 OP 正在远程主机上运行更多 bash 特定命令。
【解决方案2】:

一开始你不必为tail -n 提供+10。默认情况下它需要最后 10 行,如果要使用前 10 行,请使用 head。你为什么要使用 bash -c,如果你只是将这个命令提供给 ssh,它应该可以工作,或者检查What is the cleanest way to ssh and run multiple commands in Bash?

【讨论】:

  • 我需要提供bash -c,因为默认情况下有ksh,并且脚本不起作用。
【解决方案3】:

事实证明 这是部分 Jenkins groovy DSL 问题,但在

的帮助下

我设法绕过它。

解决办法

    sh("""ssh -o StrictHostKeyChecking=no -l <user> <host> /bin/bash << EOF
        cd /my/dir/;
        ls -1t | egrep 'regexp' | tail -n +10 | xargs rm -rf;
EOF""") 

评论

sh 插件的使用非常简单。

诀窍是将EOF 传递给/bin/bash,并且脚本的LAST 行(包含EOF不得 包含任何其他字符。 甚至 缩进 也可能导致问题,因此只需删除所有字符 - 这就是它没有“很好”对齐的原因。

然后就可以了。非常感谢大家!

【讨论】:

    【解决方案4】:

    例如,您在 txt 文件中有一个 ip 地址列表,并且您想检查每个盒子上的 java 进程数量,在进程数量之后写 ip 地址。您可以执行以下操作:

    cat ipv4.txt | xargs -I IP sh -c 'ssh username@IP "ps aux | grep java | grep -v grep | wc -l " &amp;&amp; echo IP'

    内联你的命令,玩得开心。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      相关资源
      最近更新 更多