使用awk生成一个bash命令,给出失控字符串常量 - awk

时间:2015-03-31 05:22:55

标签: linux bash awk chef

我使用awk来解析/etc/hosts并生成一个命令,为我格式化MapR。它是在bash中的Chef实用程序中完成的:

egrep '^[0-9]' /etc/hosts | grep -v 127.0.0.1 \
      | awk 'NR==1{ips=$1} 
              NR>1{ips=ips ", " $1} 
              $2=="namenode"{nn=$1} 
              END{ printf "/opt/mapr/server/configure.sh -C %s -Z %s -N mycluster --create-user -D /dev/xvdb\n", ips, nn}' \
      | bash
  sleep 60

上面的命令应该执行以下命令:

/opt/mapr/server/configure.sh -C 10.32.237.251 -Z 10.32.237.251 -N mycluster --create-user -D /dev/xvdb

但是,查看我的chef输出,我看到了:

==> namenode: Executing awk utility
==> namenode: awk: line 1: runaway string constant "/opt/mapr/ ...

该命令永远不会在MapR节点中执行...但是当我直接在终端上执行它时,它的运行方式很好。我究竟做错了什么? 我正在更新问题以显示执行该实用程序的完整bash脚本:

DISK_CONFIG=/home/ubuntu/disk_config
if [ -f $DISK_CONFIG ];
then
  echo "File already exists"
else
  echo "Executing awk utility\n"
  touch $DISK_CONFIG
  egrep '^[0-9]' /etc/hosts | grep -v 127.0.0.1 \
      | awk 'NR==1{ips=$1} 
              NR>1{ips=ips ", " $1} 
              $2=="namenode"{nn=$1} 
              END{ printf "/opt/mapr/server/configure.sh -C %s -Z %s -N mycluster --create-user -D /dev/xvdb\n", ips, nn}' \
      | bash
  sleep 60
fi

1 个答案:

答案 0 :(得分:2)

假设您在bash资源中使用HEREDOC语法:

bash "whatever" do
  code <<-EOH
    DISK_CONFIG=/tmp/disk_config
    if [ -f $DISK_CONFIG ];
    then
      echo "File already exists"
    else
      echo "Executing awk utility\n"
      touch $DISK_CONFIG
      egrep '^[0-9]' /etc/hosts | grep -v 127.0.0.1 \
          | awk 'NR==1{ips=$1}
                  NR>1{ips=ips ", " $1}
                  $2=="namenode"{nn=$1}
                  END{ printf "/opt/mapr/server/configure.sh -C %s -Z %s -N mycluster --create-user -D /dev/xvdb\n", ips, nn}' \
          | bash
    fi
  EOH
end

这个导致你的错误:

Executing awk utility

awk: line 4: runaway string constant "/opt/mapr/ ...

这是由于你的命令中的\ n(进入awk命令的那个也可能有问题)

此资源应该这样做(警告我确实替换了我的测试的DISK_CONFIG路径):

bash "whatever" do
  code <<-EOH
    DISK_CONFIG=/tmp/disk_config
    if [ -f $DISK_CONFIG ];
    then
      echo "File already exists"
    else
      echo "Executing awk utility"
      touch $DISK_CONFIG
      egrep '^[0-9]' /etc/hosts | grep -v 127.0.0.1 \
           | awk 'NR==1{ips=$1}
              NR>1{ips=ips ", " $1}
              $2=="namenode"{nn=$1}
              END{ printf "/opt/mapr/server/configure.sh -C %s -Z %s -N mycluster --create-user -D /dev/xvdb", ips, nn}' \
           | bash
      sleep 60
    fi
  EOH
end

原因是Chef已经解释了代码中的\n,所以awk看到一个字符串永无止境(失控)。

当您管道进行bash时,您可以省略\n,因为管道将结束该行。