【问题标题】:Passing variable into a function that uses awk将变量传递给使用 awk 的函数
【发布时间】:2017-11-07 15:56:27
【问题描述】:

我有一个脚本试图按名称停止某个进程(但我需要指定一个不能被杀死的特定字符串,即“notThisProcess”),然后在 20 秒后杀死它,如果它还没有到来优雅地向下,即:

#!/bin/ksh
bname=BTEST
bserver=BSERVER

PROCESS_ID=`ps auxww | awk '/PROCESS_NAME_ALPHA/ && !/awk/ && !/notThisProcess/ {print $2}'`
/apps/customapp/stopcommand -a $bname -processName PROCESS_NAME_ALPHA -serverName $bserver
sleep 20
kill -4 $PROCESS_ID

PROCESS_ID2=`ps auxww | awk '/PROCESS_NAME_BETA/ && !/awk/ && !/notThisProcess/ {print $2}'`
/apps/customapp/stopcommand -a $bname -processName PROCESS_NAME_BETA -serverName $bserver
sleep 20
kill -4 $PROCESS_ID2

#etc..

随着我的进程列表刚刚增加,我试图将这些步骤放入一个函数中,但我不知道如何将进程名称传递给 awk。即,这不起作用:

#!/bin/ksh
bname=BTEST
bserver=BSERVER

cycleProcess()
{
PROCESS_ID=`ps auxww | awk '/$1/ && !/awk/ && !/notThisProcess/ {print $2}'`
/apps/customapp/stopcommand -a $bname -processName PROCESS_NAME_ALPHA -serverName $bserver
sleep 20
kill -4 $PROCESS_ID
}

cycleProcess PROCESS_NAME_ALPHA
cycleProcess PROCESS_NAME_BETA

exit

我已经看到通过 -v 多次引用分配,但尽管多次尝试我都没有成功。有什么建议吗?

【问题讨论】:

    标签: function variables awk parameter-passing aix


    【解决方案1】:

    我会这样写:

    #!/bin/ksh
    bname=BTEST
    bserver=BSERVER
    
    cycleProcess() {
        typeset procname="$1"
        typeset pid=$(ps auxww | awk -v name="$procname" '$0 ~ name && !/awk/ && !/notThisProcess/ {print $2}')
        if [[ -z "$pid" ]]; then
            echo "$procname is not running"
            return
        fi
        /apps/customapp/stopcommand -a "$bname" -processName "$procname" -serverName "$bserver"
        sleep 20
        kill -4 "$pid"
    }
    
    processes=(
        PROCESS_NAME_ALPHA
        PROCESS_NAME_BETA
    )
    
    for proc in "${processes[@]}"; do 
        cycleProcess "$proc"
    done
    

    函数中的typeset 是一种将变量声明为该函数的局部变量的方法。

    我无权访问 AIX 机器。我的 Linux 机器上的 ps auxww 输出显示字段 11 中的命令名称,因此您可以使用 $11 == name {print $2} 代替 /name/ && !/awk/ && !/thisScript/, 或 $11 ~ name 如果匹配不准确。

    【讨论】:

    • 漂亮!非常感谢它工作得很好。第 22 行的一个小错字你有一个额外的 }。奇怪的是,它只影响了进程列表中的最后一个进程。感谢您提供优雅的解决方案!
    • 谢谢,错字已修正。在右大括号之后,额外的大括号只是一个普通字符:a=(1 2 3 4); echo "${a[@]}}"
    【解决方案2】:

    您可以在管道字符分隔列表中传递它们并与最后一个字段进行比较。

    ps ... | awk -v keep="process1|process2|process3"  '$NF!~keep{print $2}'
    

    还要注意,在您的脚本awk '/$1/ && ... 中,变量不是 bash 变量,而是传递给awk 脚本的第一个字段。

    【讨论】:

      【解决方案3】:

      正如其他人已经指出的,shell 变量可以使用选项 -v 传递给 awk 脚本。如果 awk 脚本位于单独的文件中(通过使用选项 -f),则必须使用此选项。

      当在单引号 ('...') 之间的 shell 脚本中直接指定 awk 脚本时,您还可以使用构造 ' " $shell_variable " '。请注意,这样做时,单引号和双引号之间不能有空格!

      例子:

      process_string="plugin-container"
      
      pids=$( ps -fu $LOGNAME | awk '/'"$process_string"'/ { print $2 }' )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-28
        • 1970-01-01
        • 2021-11-16
        • 2014-12-24
        • 1970-01-01
        • 2019-03-21
        • 2020-07-28
        • 1970-01-01
        相关资源
        最近更新 更多