将变量传递给使用 awk 的函数

Passing variable into a function that uses awk

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

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

PROCESS_ID=`ps auxww | awk '/PROCESS_NAME_ALPHA/ && !/awk/ && !/notThisProcess/ {print }'`
/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 }'`
/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 '// && !/awk/ && !/notThisProcess/ {print }'`
/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 进行赋值的引用,但尽管进行了多次尝试,但我没有成功。有什么建议吗?

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

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

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

我会这样写:

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

cycleProcess() {
    typeset procname=""
    typeset pid=$(ps auxww | awk -v name="$procname" '[=10=] ~ name && !/awk/ && !/notThisProcess/ {print }')
    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 中的命令名称,因此您可以使用 == name {print } 而不是 /name/ && !/awk/ && !/thisScript/, 或 ~ name 如果匹配不准确。

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

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

示例:

process_string="plugin-container"

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