【问题标题】:Escape characters in AWK script within bash scriptbash 脚本中 AWK 脚本中的转义字符
【发布时间】:2019-12-17 20:36:47
【问题描述】:

此代码在 AWK 之外按预期工作

password_cmd="kubectl get secrets -o jsonpath=\'{.data.ssl-store-password}\' -n $namespace $password_secret"
echo $password_cmd
password=eval $password_cmd

输出:

kubectl get secrets -o jsonpath=\'{.data.ssl-store-password}\' -n aircourier secret-aircourier-mq-password

在 AWK 中使用它时,我在转义引号时遇到问题

第一次尝试

password_cmd="kubectl get secrets -o jsonpath=\'\''{.data.ssl-store-password}\'\'' -n $namespace $password_secret";

输出

awk: cmd. line:9: warning: escape sequence `\'' treated as plain `''

第二次尝试

password_cmd='\''kubectl get secrets -o jsonpath=\'\''{.data.ssl-store-password}\'\'' -n $namespace $password_secret'\'';

输出

awk: cmd. line:9:       password_cmd='kubectl get secrets -o jsonpath=\'{.data.ssl-store-password}\' -n $namespace $password_secret';
awk: cmd. line:9:                    ^ invalid char ''' in expression

到目前为止的完整脚本

#!/bin/bash
kubectl get secrets --all-namespaces | grep jks > keystores.tmp


# create table headers in the file for manage engine
echo '<--table K8_jks_secrets starts-->' > table.out
echo 'Namespace , Secret Name, Expire Date, Days Remaining' >> table.out

# awk through each line in keystores.tmp that we created earier
awk '{
    #print $1, ", " $2, ", ";
    namespace=1;
    jks_secret=2;
    print $namespace, ", " $jks_secret, ", ";
    $password_secret=substr($2,1,length($2)-3)"password";
    print $password_secret

    password_cmd='\"'kubectl get secrets -o jsonpath=\'\''{.data.ssl-store-password}\'\'' -n $namespace $password_secret'\"';
    print $password_cmd ;

}' keystores.tmp >> table.out

echo '<--table K8_jks_secrets starts-->' >> table.out

【问题讨论】:

  • JSON 片段周围的文字单引号几乎可以肯定是一个错误。
  • 您的实际 Awk 代码在哪里?
  • shell 变量肯定不会被 Awk 扩展。 You should properly quote them in the shell,但如果这是有代表性的,您的 awk 脚本可能包含更多错误。
  • namespace=1; 然后... $namespace 可能无法按您的预期工作。只需在 awk 中进行测试,即。 awk 'END{namespace=1; print "ns=" $namespace}' /dev/null 。祝你好运。
  • 另一个 awk 测试是 echo "one two" | awk '{namespace=1; print "ns=" $namespace}' 。祝你好运。

标签: bash awk escaping quoting


【解决方案1】:

我最终使用了 while read 循环,可能不是最好的解决方案,但它可以满足我的需要。

#!/bin/bash
#This script is triggered by Manage Engine and checks certificate expire dates of all K8 Pod jks secrets
# get all jks secrets in K8 and write them to a temp file that we can read through later

#suppress the warning generated from java keystore command
exec 2> /dev/null
#Warning:
#The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".



#run kubectl command to get all secrets that are jks 
kubectl get secrets --all-namespaces | grep jks > keystores.tmp


# create table headers in the file for manage engine
echo '<--table K8_jks_secrets starts-->' > cert_dates_table.out
echo 'Namespace , Secret Name, Expire Date, Days Remaining' >> cert_dates_table.out

# read through each line in keystores.tmp that we created earier
while read -r line; do

    #remove unneeded spaces from the line so that cut can use ' ' as delimiter
    new_line=$(echo $line | sed -e "s/  */ /g")
    #echo "$new_line"

    #namespace is the first field
    namespace=$(echo "$new_line" | cut -d ' ' -f 1)
    #echo $namespace

    #jks secret name is the second field
    jks_secret=$(echo "$new_line" | cut -d ' ' -f 2)
    #echo $jks_secret

    #The password secrect name is awlays the same as the jks secrect name but with "password" instead of "jks" on the end
    #trim the "jks" and add "password" instead
    password_secret=${jks_secret::-3}"password"
    #echo $password_secret

    #This command will extract and decode the password secret
    password_cmd="kubectl get secrets -o jsonpath=\'{.data.ssl-store-password}\' -n $namespace $password_secret | cut -c 2- | head -c -2 | base64 -d "
    #echo $password_cmd
    password=$(eval $password_cmd)
    #echo "password: "$password

    #this command will extract and decode the jks secret and store it in a file so that we can run the java keytool command on it later
    jks_cmd="kubectl get secrets -o jsonpath=\'{.data}\' -n $namespace $jks_secret | cut -d':' -f2 | cut -d']' -f1 | base64 -d "
    #echo $jks_cmd
    eval $jks_cmd > keystore.jks
    #echo $jks_base64

    #using keytool we read the jks and grep for all lines containing 'Valid from' as both valid from and expiry date is shown on the same line
    #output all the lines with Valid From and Expiry Dates into a temp file we will read later
    keytool_cmd="keytool -list -v -storepass "\'"$password"\'" -keystore keystore.jks | grep 'Valid from'"
    #echo $keytool_cmd 
    eval $keytool_cmd > dates.tmp
    #echo $keystore_readable

    #for each jks read through each date and output the fields into the manage Engine cert_dates_table.out
    while read -r date_line; do
        #cut the line to just include the Expirey date
        string_date=$(echo "$date_line" | cut -c 53-)
        #echo $string_date

        #convert the string date to a date
        cert_date=$(date -d ''"$string_date"'' +%s)
        #echo $cert_date

        #put the current system date into a variable
        system_date=$(date +%s)

        #calculate the differnace in days between today and the cert expire date
        day_left=$(( (cert_date - system_date) / 86400 ))
        #echo $day_left

        echo $namespace ","  $jks_secret ", " $string_date ", " $day_left >> cert_dates_table.out

    done < dates.tmp


done < keystores.tmp

#delete the tmp files created
rm -f dates.tmp
rm -f keystores.tmp
rm -f keystore.jks

#End the table for Manage Engine
echo '<--table K8_jks_secrets ends-->' >> cert_dates_table.out

【讨论】:

    【解决方案2】:

    将您的 awk 脚本放在一个单独的文件中。这样您就不必担心 bash 和 awk 退出如何交互。您的 awk 命令将变为:

    awk -f foo.awk keystores.tmp >> table.out
    

    据我所知,您的脚本没有使用任何 bash 变量,所以应该可以解决问题!

    编辑如果你真的想运行password_cmd,你可以在你的awk脚本中使用system或getline。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 2011-07-10
      • 2014-02-02
      • 1970-01-01
      相关资源
      最近更新 更多