修改awk代码块中的shell变量

时间:2016-01-19 00:41:59

标签: bash shell variables awk

有没有办法在awk代码块中修改shell变量?

static int handle_packet(struct nfq_q_handle* qh, struct nfgenmsg* nfmsg, struct nfq_data* dat, void* data)
{
    struct nfqnl_msg_packet_hdr* nfq_hdr = nfq_get_msg_packet_hdr(dat);
    unsigned char* nf_packet;
    int len = nfq_get_payload(dat,&nf_packet);
    struct iphdr *iph = ((struct iphdr *) nf_packet);
   iphdr_size = iph->ihl << 2;

    if (iph->protocol == 6){
        struct tcphdr *tcp = ((struct tcphdr *) (nf_packet + iphdr_size));    
        unsigned short tcphdr_size = (tcp->doff << 2);

        printf("\nGot a packet!! len: %d iphdr: %d tcphdr: %d", len, iphdr_size, tcphdr_size);
    }
}

这是一个非常简单的例子,真正的脚本加载文件并使用函数进行一些更改,我需要在更改为特定变量之前保留每个值,这样我就可以在值之前和之后注册到MySQL。 / p>

从参数($ 1,$ 2等)收到后值。

之前的值我已经知道如何从文件中获取它。

除了shell_variable由awk变量设置外,一切都很顺利。在awk之外的区块代码很容易设置,但在内部,是否可能?

1 个答案:

答案 0 :(得分:5)

没有程序 - 以awk,shell或任何其他语言 - 可以直接修改父进程的内存。这包括变量。但是,当然,您的awk可以将内容写入stdout,父shell可以读取该内容并自行修改自己的变量。

这是一个awk的示例,它将键/值对写入以供bash读取。它并不完美 - 请阅读下面的注意事项。

#!/bin/bash

shell_variable_1=10
shell_variable_2=20
shell_variable_3=30

run_awk() {
        awk -v shell_variable_1="$shell_variable_1" \
            -v shell_variable_2="$shell_variable_2" \
            -v shell_variable_3="$shell_variable_3" '
        function A(X) { return X+1 }
        { a=A(shell_variable_1)
          b=A(shell_variable_2)
          c=A(shell_variable_3) }
        END {
          print "shell_variable_1=" a
          print "shell_variable_2=" b
          print "shell_variable_3=" c
        }' <<<""
}

while IFS="=" read -r key value; do
        printf -v "$key" '%s' "$value"
done < <(run_awk)

for var in shell_variable_{1,2,3}; do
  printf 'New value for %s is %s\n' "$var" "${!var}"
done

优点

  • 不使用eval。您的shell不会执行$(rm -rf ~)输出中的awk等内容。

缺点

  • 无法使用换行符处理变量内容。 (您可以通过NUL分隔awk脚本的输出并将-d ''添加到read命令来解决此问题。
  • 恶意awk脚本可以修改PATHLD_LIBRARY_PATH或其他安全敏感变量。 (您可以通过将变量读入关联数组而不是全局命名空间,或通过在其名称上强制使用前缀来解决此问题。)
  • 上面的代码使用了bash中也提供的几个ksh扩展名;但是,它将与POSIX sh一起运行。因此,请确保不要通过sh scriptname(仅保证POSIX功能)来运行此功能。