Вопрос или проблема
Какие есть варианты, не используя внешние команды, для отображения разрешений файла?
test
является встроенной командой, но, насколько я знаю, работает только для владельца файла. Мне нужны все разрешения. Думал, что нашел решение с inodes
, но не могу найти способ их прочитать (с помощью встроенных функций!).
Только bash
, пожалуйста. Любая версия и/или формат допустимы.
редактировать:
Я знаю, что существует множество способов сделать это с помощью внешних команд (stat
, ls
и т.д.), это просто мыслительный эксперимент — мне не обязательно решать задачу, используя только builtin
.
редактировать2:
Ответ Гленна Джэкмана с загружаемыми командами технически верен, так как он использует встроенную команду. Однако, думаю, это просто показывает, что мой вопрос был плохо сформулирован.
Используя чистые bash
(любая версия) builtin
команды, как перечислено в мануале, и другие встроенные функции bash
(перенаправление, замена, ключевые слова, и другие функции, о которых я даже не знаю…), на linux
системе, как я могу отобразить полные разрешения файла? Вывод будет похож на любой из приведенных ниже, хотя значение umask тоже подойдет.
user@hostname$ stat test -c %A
-rw-rw-r--
user@hostname$ stat test -c %a
664
В обычном bash, я думаю, лучшее, что вы можете получить, это что-то вроде этого: вы получаете ваши права доступа, а не группы или других.
myperms() {
local file=$1
local perms=""
if [[ -d $file ]]; then
perms+='d'
elif [[ -L $file ]]; then
perms+='l'
else
perms+='-'
fi
[[ -r $file ]] && perms+='r' || perms+='-'
[[ -w $file ]] && perms+='w' || perms+='-'
[[ -x $file ]] && perms+='x' || perms+='-'
echo "$perms $file"
}
Тогда:
$ myperms /bin/bash
-r-x /bin/bash
$ touch afile
$ myperms afile
-rw- afile
$ chmod u+x afile
$ myperms afile
-rwx afile
$ ln -s afile alink
$ myperms alink
lrwx alink
$ chmod u-wx afile
$ myperms alink
lr-- alink
$ ls -l afile alink
-r--r--r-- 1 glennjackman staff 0 Dec 16 14:28 afile
lrwxr-xr-x 1 glennjackman staff 5 Dec 16 14:29 alink -> afile
С bash версии 5 существуют “загружаемые команды” — команды, которые не являются встроенными командами bash, но могут быть включены, чтобы стать встроенными:
- клонируйте репозиторий bash с git: https://savannah.gnu.org/git/?group=bash
./configure --prefix=/путь/где/вы/хотите/его/установить
- make && make install
stat
не является “поддерживаемым” загружаемым, даже если он здесь существует, так чтоcd ./examples/loadables
make others
cp stat /путь/где/вы/хотите/его/установить/lib/bash
Тогда
- Запустите bash shell:
/путь/где/вы/хотите/его/установить/bin/bash
- установите переменную shell:
BASH_LOADABLES=/путь/где/вы/хотите/его/установить/lib/bash
- включите команду stat:
enable -f stat stat
- и используйте ее:
stat -A statarray /some/file
stat
заполняет ассоциативный массив. Демонстрация (используя массив по умолчанию с именем “STAT”)
$ ~/bash/5.0/bin/bash
$ echo $BASH_LOADABLES_PATH
/Users/glennjackman/bash/5.0/lib/bash
$ enable -f stat stat
$ stat ~/.bashrc
$ declare -p STAT
declare -A STAT=([nlink]="1" https://superuser.com/questions/1510463/builtin-way-to-list-file-permissions-in-linux="/Users/glennjackman/.bashrc" [perms]="0644" [inode]="14482796" [blksize]="4096" [device]="16777220" [atime]="1574454147" [type]="-" [blocks]="8" [uid]="502" [size]="2767" [rdev]="0" [name]="/Users/glennjackman/.bashrc" [mtime]="1574454147" [ctime]="1574454147" [gid]="20" )
$ for key in "${!STAT[@]}"; do printf "%s\t%s\n" "$key" "${STAT[$key]}"; done
nlink 1
link /Users/glennjackman/.bashrc
perms 0644
inode 14482796
blksize 4096
device 16777220
atime 1574454147
type -
blocks 8
uid 502
size 2767
rdev 0
name /Users/glennjackman/.bashrc
mtime 1574454147
ctime 1574454147
gid 20
Чтобы автоматически установить переменную BASH_LOADABLE_PATH, я добавил в свой ~/.bashrc:
# для встроенных загружаемых
bash_root=${BASH%/bin/bash}
[[ -d "$bash_root/lib/bash" ]] && BASH_LOADABLES_PATH="$bash_root/lib/bash"
unset bash_root
Последние абзацы относятся к оригинальному посту, но они имеют смысл только после обсуждения встроенных команд, особенно тех, которые не загружаются по умолчанию.
Переменная BASH_LOADABLES_PATH – это переменная Bash, которая не является env переменной, поэтому вы могли ее пропустить, если не заметили в man-странице Bash. Как и ожидалось, она сообщает Bash, где искать встроенные команды.
На моей системе Debian, из нескольких путей в BASH_LOADABLES_PATH существовал только /usr/lib/bash, прежде чем я создал свой собственный. Согласно info bash
, значение по умолчанию (для BASH_LOADABLES_PATH) зависит от системы, так что, возможно, не полагайтесь на /usr/lib/bash. Но не устанавливайте/перезаписывайте BASH_LOADABLES_PATH, лучше размещайте новые встроенные команды в подходящем пути, найденном в BASH_LOADABLES_PATH. Я создал /usr/local/lib/bash, который уже был в BASH_LOADABLES_PATH, затем поместил туда свои встроенные команды Bash.
На моей системе есть несколько команд в директории /usr/lib/bash, кроме stat
, некоторые из которых не представлены в /usr/bin. Эти команды могут быть доступны только при включении, и без man-файлов аргумент help – это их единственная документация.
Нет необходимости в аргументе -f
для библиотек общих объектов, найденных в директориях BASH_LOADABLES_PATH.
Относительно оригинального поста:
Существует встроенная команда stat
, которая работает иначе, чем команда stat
. Я не знаю, есть ли она на каждой системе (вопрос о том, гарантировано ли ее наличие, и привел меня к этой теме), но попробуйте включить ее, а затем получите помощь.
$ enable stat
$ help stat
Встроенная stat
является оберткой над функцией stat из glibc. Обратитесь к man 3type stat
, чтобы узнать, какую информацию раскрывает встроенная stat
, или вы можете просто перебрать ключи ассоциативного массива.
К сожалению, встроенная stat
не раскрывает разрешения. Однако, если она доступна на вашей системе, включите и получите помощь по встроенной finfo
, чтобы узнать ее возможности. Опции -o
и -p
функции finfo
возвращают разрешения в восьмеричном и ASCII форматах, соответственно. Опция -U
возвращает имя пользователя, а -G
— группу пользователя.
.
Ответ или решение
При поиске способа вывести права доступа к файлу в Linux с использованием исключительно встроенных команд Bash, стоит учитывать ограничения этого подхода. Встроенные команды, такие как test
, действительно могут определять права только для владельца файла, и, к сожалению, нет прямого способа в чистом Bash получить полные права доступа к файлу (относительно всех пользователей) без использования внешних утилит вроде ls
или stat
. Тем не менее, есть несколько подходов, которые могут быть полезны для достижения этой цели в рамках интеллектуального упражнения.
Использование встроенных команд Bash для определения прав текущего пользователя:
Функция Bash, представленная ниже, позволяет вам определить права доступа для текущего пользователя к заданному файлу:
myperms() {
local file=$1
local perms=""
if [[ -d $file ]]; then
perms+='d'
elif [[ -L $file ]]; then
perms+='l'
else
perms+='-'
fi
[[ -r $file ]] && perms+='r' || perms+='-'
[[ -w $file ]] && perms+='w' || perms+='-'
[[ -x $file ]] && perms+='x' || perms+='-'
echo "$perms $file"
}
Этот скрипт позволяет определить, какие права доступа у текущего пользователя к указанному файлу, и отличается тем, что не требует использования каких-либо внешних команд.
Использование загружаемых команд в Bash версии 5:
В версии 5 Bash появились "загружаемые команды". Эти команды, хоть и не встроены по умолчанию, могут быть добавлены в среду Bash, что превращает их в своего рода встроенные команды. Вот шаги для их настройки:
- Клонируйте Bash git-репозиторий: Git Repository.
- Настройте и установите Bash в необходимую директорию:
./configure --prefix=/path/where/you/want/it/installed make && make install
- Загрузите необходимые команды. Например, для
stat
, который тут выступает как загружаемое расширение:cd ./examples/loadables make others cp stat /path/where/you/want/it/installed/lib/bash
После установки откройте новый Bash-сеанс и выполните следующие команды:
- Установите переменную
BASH_LOADABLES
для указания пути к загрузке:BASH_LOADABLES=/path/where/you/want/it/installed/lib/bash
- Включите команду
stat
:enable -f stat stat
- Используйте ее для получения информации о файле:
stat -A statarray /some/file
Эти шаги позволяют использовать команду stat
, которая возвращает массив с различной информацией о файле, включая права доступа в числовом формате.
Заключение
Даже если цель использования только встроенных команд Bash может быть ограничительна, использование загружаемых расширений предоставляет некоторые дополнительные возможности. Это решение позволяет глубже понять архитектуру Bash и способы работы с различными расширениями в Unix-системах. В контексте модернизации процесса часто бывает целесообразно использовать стандартные утилиты Linux, чтобы повысить эффективность и точность.