skip to Main Content

I have a bootstrap script. After every time it runs, I want to keep track of its exit status in a JSON file. JSON file can have other fields too.

Case 1: The very first time it runs, JSON file will be created & a field node_bootstrap_status with boolean value will be added to it.

Case 2: In subsequent runs, JSON file will pre-exist. But in this case, I want to update same JSON field node_bootstrap_status with the outcome(again boolean).

I wrote the following bash script. It works for 1st case. In second case however, it ends up deleting everything in pre-existing JSON file.

exit_code=1

node_info_file="/etc/node_info.json"


if [[ -f $node_info_file ]]; then
  # /etc/node_info.json exists
  echo "${node_info_file} exists"
  if [ $exit_code = 0 ]; then
    cat $node_info_file | jq --argjson node_bootstrap_status true '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  else
    cat $node_info_file | jq --argjson node_bootstrap_status false '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  fi  
else
  # /etc/node_info.json does NOT exists
  echo "${node_info_file} does not exist"
  touch ${node_info_file}
  if [ $exit_code = 0 ]; then
    echo '{}' | jq --argjson node_bootstrap_status true '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  else
    echo '{}' | jq --argjson node_bootstrap_status false '{"node_bootstrap_status": $node_bootstrap_status}' > $node_info_file
  fi  
fi

expected outcome:

cat /etc/node_info.json 
{
  "node_bootstrap_status": true/false,
  "foo": "bar"
}

2

Answers


  1. You’re off to a good start – but you’d want to use assignment rather than the sort of { ... } syntax like so:

    node_info_file="node_info.json"
    
    set_status() {
        local value="$1"
    
        mv -f "$node_info_file" "$node_info_file.tmp"
    
        # Set property key with: '.node_bootstrap_status = ...'
        jq --argjson node_bootstrap_status "$value" '.node_bootstrap_status = $node_bootstrap_status' "$node_info_file.tmp" > "$node_info_file"
    
        rm -f "$node_info_file.tmp"
    }
    
    # if node_info.json does NOT exists; create it
    if [ ! -f $node_info_file ]; then
        printf '%sn' '{}' > "$node_info_file"
    fi
    
    set_status true
    set_status false
    

    I tested this with empty JSON, and with other contents, and it worked as expected.

    Also, make sure you quote "$node_info_file" – it’s good practice. If you use ShellCheck then it’ll catch those types of errors for you.

    Login or Signup to reply.
  2. Try to adapt this version to your needs :

    #!/usr/bin/env bash
    
    exit_code=1
    node_info_file="/etc/node_info.json"
    
    test -f "$node_info_file" || echo {} > "$node_info_file"
    [ $exit_code = 0 ] && status=true || status=false
    tmp=$(mktemp)
    jq --argjson node_bootstrap_status $status '{$node_bootstrap_status}' "$node_info_file" > $tmp
    mv $tmp "$node_info_file"
    

    Just a side note, it may not be a good idea to save node_info.json in /etc.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search