If your shell is a POSIX one, and user and group names don't contain space characters, you can use the split+glob operator (invoked implicitly when you leave parameter expansions, command substitution or arithmetic expansion unquoted in list contexts):
IFS=' ' # split on space only
set -o noglob # disable the glob part
output=$(LC_ALL=C ls -Lld bin) || exit # exit if bin can't be stat()ed.
set -- $output # split+glob $output and assign result to positional parameters
mode=$1 # could also contain +, @... to specify system-dependent extra
# information such as the presence of ACLs or extended attributes
links=$2 user=$3 group=$4 size=$5
If you can't guarantee user and group names won't contain space characters, you could use ls -n instead of ls -l and you'd then get the uid and gid in $user and $group which may be enough for your needs.
With sed, you could use it to parse the first line of the output of ls and generate the shell code that sets the variables:
get_credentials() {
eval "$(
sp=' \{1,\}' nsp='[^ ]\{1,\}'
LC_ALL=C ls -Lld -- "${1?}" |
LC_ALL=C sed -n "
/^$nsp$sp$nsp$sp\($nsp\)$sp\($nsp\).*$/ {
s//\1 \2/
s/'/'\\\\''/g
s/\($nsp\) \($nsp\)/user='\1' group='\2' ||/p
}
q"
) false"
}
To be used as:
get_credentials bin || exit
printf 'The %s name is: "%s"\n' user "$user" \
group "$group"
That would evaluate the user='the-user' group='the-group' || false shell code (or user='o'\''connor'... for o'connor for instance) if the user and group names can be extracted from the first line of ls output, or false otherwise.
statwould suit your needs? – doneal24 Aug 12 '21 at 19:47statis a part of GNU coreutils, as isls. Seewhereis stat(s/b: /usr/bin/stat) – JRFerguson Aug 12 '21 at 20:19stat? Doesfind / -prune -printf '%g:%u\n'print something likeroot:root? or is there an error? – Kamil Maciorowski Aug 12 '21 at 20:21