Bash поддерживает переменную косвенность:
#!/bin/bash
MARCOMIN=1
MARCOMAX=3
ENZOMIN=1
ENZOMAX=3
GIOVANNIMIN=1
GIOVANNIMAX=3
VALUEMARCO=12
VALUEGIOVANNI=4
VALUEENZO=12
for i in MARCO ENZO GIOVANNI; do
for j in MIN MAX VALUE; do
varname="${i}${j}"
# For VALUE we need reverse order of i and j
[[ $j = VALUE ]] && varname="${j}${i}"
printf "%d is %s's %s\n" "${!varname}" "$i" "$j"
done
done
exit 0
Я сделал немного больше с внутренним циклом и использовал printf
вместо echo
, но основная идея заключается в том, что по имени переменной foo
, хранящемуся в другой переменной bar
, вы можете получить значение $foo
, выполнив ${!bar}
.
Подробнее:https://stackoverflow.com/questions/8515411/what-is-indirect-expansion-what-does-var-mean
Тест -f
будет верным, если заданное имя является именем обычного файла или символической ссылкой на обычный файл. Тест -h
будет верным, если данное имя является именем символической ссылки. Это задокументировано как вman test
(или man [
), так и в help test
в сеансе оболочки bash
. Оба теста являются стандартными тестами , которые может реализовать любая утилита POSIX test
и [
.
name=something
if [ -f "$name" ] && ! [ -h "$name" ]; then
# "$name" refers to a regular file
fi
То же самое с использованием stat
в OpenBSD (следующие фрагменты кода также используют стандартный тест -e
только для того, чтобы убедиться, что имя существует в файловой системе перед вызовомstat
):
name=something
if [ -e "$name" ] && [ "$(stat -f %Hp "$name")" = "10" ]; then
# "$name" refers to a regular file
fi
(тип файла 10
указывает на обычный файл ).
При использовании GNUstat
:
name=something
if [ -e "$name" ] && [[ $(stat --printf=%F "$name") == "regular"*"file" ]]; then
# "$name" refers to a regular file
fi
Шаблон в этом последнем тесте соответствует обеим строкам: regular file
и regular empty file
.
Решение stat
по запросу.
stat --printf "%F" file-name
см. выдержку из руководства (ниже)
-c --format=FORMAT
use the specified FORMAT instead of the default; output a newline after each use of FORMAT
--printf=FORMAT
like --format, but interpret backslash escapes, and do not output a mandatory trailing newline;
if you want a newline, include \n in FORMAT
The valid format sequences for files (without --file-system):
%F file type
GNU coreutils 8.30