系统调用

时间:2017-01-24 04:52:39

标签: awk

我有以下shell脚本:

#!/bin/bash

top -n 1 -p $(pgrep -d',' -f R) | grep R | awk '{if ($2 != "PID" && int($10) > 50) 
{
    kill_cmd = "echo kill " $1 " | bash -";
    system(kill_cmd);
}}'

如果我将系统调用更改为print语句,结果输出看起来像我期望的那样:echo kill <some_pid> | bash -我也能够无错误地运行print语句的输出。

系统调用错误说明:意外令牌附近的语法错误`(&#39;

该脚本的目的是使用top来查看正在运行的R进程,并在它们使用超过50%的系统内存时终止它们。

3 个答案:

答案 0 :(得分:1)

在您的情况下,下面的陈述是错误的,您不需要echo|bash -

kill_cmd = "echo kill " $1 " | bash -";
system(kill_cmd);

你可以使用(注意:确保PID列在1美元,它应该是2美元,我猜

$ top -n 1 -p $(pgrep -d',' -f R) | 
  awk '/R/ && $2 != "PID" && int($10) > 50{system("kill " $2 )}'

如下所示

$ awk 'BEGIN{system("date")}'
Tue Jan 24 12:41:08 IST 2017

不是每次都调用system(),而是可以在最后管道

<强>要么

$ top -n 1 -p $(pgrep -d',' -f R) | 
  awk '/R/ && $2 != "PID" && int($10) > 50{ print "echo kill " $2 }' | bash

$ top -n 1 -p $(pgrep -d',' -f R) | 
  awk '/R/ && $2 != "PID" && int($10) > 50{ print  $2 }' | xargs kill -9

例如

$ awk 'BEGIN{for(i=1;i<=5;i++)print "echo test :"i; print "date"}' 
echo test :1
echo test :2
echo test :3
echo test :4
echo test :5
date

$ awk 'BEGIN{for(i=1;i<=5;i++)print "echo test :"i; print "date"}'  | bash
test :1
test :2
test :3
test :4
test :5
Tue Jan 24 12:31:43 IST 2017

答案 1 :(得分:1)

  

该脚本的目的是使用top来查看正在运行的R进程,并在它们使用超过50%的系统内存时终止它们。

为此目的,我不会在pgrep之前使用topgrep,也不会使用任何无用的awk

ps aux | awk '$11 ~/R/ && $4 > 50 { system("kill " $2) }'

ps aux | awk '$11 ~/R/ && $4 > 50 { print $2 }' | xargs kill

这已在Linux上测试过。根据系统中ps输出的特定格式,美元参数的编号可能不同(您可能还希望通过提供不同的参数来指示ps使用其他输出格式或流程选择来自aux。)此外,也许匹配~/R/可能应该被改进,但它与您使用的相同。在一个命令行中收集PID后,xargs仅调用kill一次,除非它们太多,在这种情况下xargs将PID分成适当数量的{{1}调用(在这种情况下是不可能的,因为你不能拥有数十个进程,每个进程占用系统内存的50%以上......)

答案 2 :(得分:0)

#!/bin/bash

eval "$( 
   top -n 1 -p $(pgrep -d',' -f R) \
    | awk '
        /R/ && $10 >= 51 && $2 != "PID" { L = L " " $1 } 
        END { if ( L !~ /^$/) print "kill" L }
        '
    )"
  • eval只调用一次通过子shell为所有PID杀死(杀死允许杀死几个pid作为参数传递
  • 不需要grep R后跟awk,awk可以使用/R/过滤
  • 简单测试通常可以作为过滤器而不是if inside structure
  • 可能会添加一个信号级别(最终通过传递给awk的变量)以获取级别