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
....