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 eval
uate 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.
stat
would suit your needs? – doneal24 Aug 12 '21 at 19:47stat
is 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