Home > Software engineering >  Having problems trying to figure out how to print variable values using this new bash-ism I'm e
Having problems trying to figure out how to print variable values using this new bash-ism I'm e

Time:10-17

Good day all. I'm trying to learn if this is possible to do. I've been writing scripts in #!/bin/sh mode (interpreted with bash) for a while but am learning about bash-isms and am using #!/bin/bash. I am using shellcheck and checkbashisms to help me and I am wondering if what I hope to accomplish is easy. I'm using stat -s in a script which populates variables and I'm trying to cycle through them all to print to screen. Below is the minimal amount of code which demonstrates what I'm asking.

I couldn't quite find a previously asked question which is similar. I have a feeling an array might be the way to accomplish what I'm hoping, but I thought I'd ask about this.

!/bin/bash

T_FILE=/var/log/fsck_hfs.log

s_vars=( st_dev=0\
         st_ino=0\
         st_mode=0\
         st_nlink=0\
         st_uid=0\
         st_gid=0\
         st_rdev=0\
         st_size=0\
         st_atime=0\
         st_mtime=0\
         st_ctime=0\
         st_birthtime=0\
         st_blksize=0\
         st_blocks=0\
         st_flags=0 )

eval "$(stat -s "$T_FILE")"

printf "\n\n%d\n\n" "$st_size"

for var in "${s_vars[@]}"; do
        printf "%s\n" "$var"
done

As the more seasoned among you will probably notice straight away my for loop using that bash-ism will print the literals in s_var and I'd like them to print the values. I'd guess I'm going about this completely the wrong way, so any pointers would be appreciated. I've tried changing the %s format specifier in that for loop to a %d but it correctly points out invalid number.

Here is a sample run of my code:

king:photosync hank$ ./stat.sh


3614

st_dev=0
st_ino=0
st_mode=0
st_nlink=0
st_uid=0
st_gid=0
st_rdev=0
st_size=0
st_atime=0
st_mtime=0
st_ctime=0
st_birthtime=0
st_blksize=0
st_blocks=0
st_flags=0
king:photosync hank$

CodePudding user response:

Like so:

#!/bin/bash

t_file=/var/log/fsck_hfs.log

s_vars=(
     # Remove =0
     # remove slashes
     # Just list the names
     # you can safely put newlines and comments in array declaration
     st_blksize
     st_blocks
     st_flags
     # etc...
)

eval "$(stat -s "$t_file")"

for var in "${s_vars[@]}"; do
        printf "%s=%s\n" "$var" "${!var}"
        #                        ^^^^^^^ - bash indirect expansion
done

You could for example extract the list of variables from output of the command, assuming the output is nice one line per var=val, like:

tmp=$(stat -s "$t_file")
s_vars=( $(sed 's/=.*//' <<<"$tmp") )  # I know, shellcheck
eval "$tmp"
for i in "${s_vars[@]}"; do
    ....
  •  Tags:  
  • bash
  • Related