У обоих есть свои причуды, к сожалению.
Оба требуются POSIX, поэтому разница между ними не является проблемой переносимости¹.
Обычный способ использования утилит таков
base=$(basename -- "$filename")
dir=$(dirname -- "$filename")
Обратите внимание на двойные кавычки вокруг замен переменных, как всегда, а также на --
после команды, на случай, если имя файла начинается с тире (иначе команды будут интерпретировать имя файла как опцию). Это все еще не работает в одном крайнем случае, который встречается редко, но может быть вынужденным злоумышленником²: при подстановке команд удаляются идущие после них новые строки. Поэтому если имя файла называется foo/bar
, то base
будет установлено в bar
вместо bar
. Обходным решением является добавление символа не новой строки и удаление его после подстановки команды:
base=$(basename -- "$filename"; echo .); base=${base%.}
dir=$(dirname -- "$filename"; echo .); dir=${dir%.}
С подстановкой параметров вы не столкнетесь с крайними случаями, связанными с расширением странных символов, но есть ряд трудностей с символом слэша. Одна вещь, которая совсем не является краевым случаем, заключается в том, что вычисление части каталога требует другого кода для случая, когда нет /
.
base="${filename##*/}"
case "$filename" in
*/*) dirname="${filename%/*}";;
*) dirname=".";;
esac
Крайний случай - это когда есть косая черта (включая случай корневого каталога, который весь состоит из косых черт). Команды basename
и dirname
отделяют косые черты перед выполнением своей работы. Если вы придерживаетесь POSIX-конструкций, нет способа убрать косые черты за один раз, но вы можете сделать это в два этапа. Вам нужно позаботиться о случае, когда входные данные состоят из одних слэшей.
case "$filename" in
*/*[!/]*)
trail=${filename##*[!/]}; filename=${filename%%"$trail"}
base=${filename##*/}
dir=${filename%/*};;
*[!/]*)
trail=${filename##*[!/]}
base=${filename%%"$trail"}
dir=".";;
*) base="/"; dir="/";;
esac
Если вы знаете, что у вас не крайний случай (например, результат find
, отличный от начальной точки, всегда содержит часть каталога и не имеет косых /
), то манипуляции со строкой расширения параметров просты. Если вам нужно справиться со всеми крайними случаями, то утилиты проще в использовании (но медленнее).
Иногда вы можете захотеть обрабатывать foo/
как foo/.
, а не как foo
. Если вы действуете на записи каталога, то foo/
должно быть эквивалентно foo/.
, а не foo
; это имеет значение, когда foo
является символической ссылкой на каталог: foo
означает символическую ссылку, foo/
означает целевой каталог. В этом случае базовое имя пути с косой чертой выгодно отличается от .
, и путь может быть собственным именем dirname.
case "$filename" in
*/) base="."; dir="$filename";;
*/*) base="${filename##*/}"; dir="${filename%"$base"}";;
*) base="$filename"; dir=".";;
esac
Быстрый и надежный метод - использовать zsh с его модификаторами истории (сначала удаляет косые черты, как и утилиты):
dir=$filename:h base=$filename:t
¹ Если только вы не используете оболочки, предшествующие POSIX, например, /bin/sh
в Solaris 10 и старше (в которой отсутствовали функции манипуляции строками расширения параметров на машинах, все еще находящихся в производстве - но в установке всегда есть POSIX-оболочка под названием sh
, только это /usr/xpg4/bin/sh
, а не /bin/sh
).
² Например: отправьте файл с именем foo
на службу загрузки файлов, которая не защищена от этого, затем удалите его, и вместо него будет удален foo
На скриншоте я делаю вывод, что это немецкая версия.
Какой рабочий стол, корицу и т. д. вы используете? И после какого мануала был установлен GUI по отпечатку пальца -? Включает ли ваша установка GUI отпечатка пальца -пакет libbsapi?
У меня проблема с читателем HP Probook 470 G5, FP -"VFS495 138a :003f" под LM19 Cin. с lightdm графический интерфейс Fingerprint -не находит драйвер.
Здравствуйте, а также спасибо за ответ. Я также использую Cinnamon и уже попробовал инструкции ubuntuusers.de для моего считывателя отпечатков пальцев, чтобы он мог двигаться. Но, к сожалению, пока это не удается, потому что устройство не поддерживается или демон не был запущен для входа в систему. Мой читатель FP видимо не поддерживается.
Я также попробовал учебник Петра Бобока:https://github.com/PetreBoboc/vfs495/blob/master/vfs495_ubuntu_18.04.mdно тоже не работает, логин просто не запрашивается после "Входа" в FP-Reader. Окно входа в систему всегда сообщает «неправильный пароль....»
Если это работает для вас, дайте отзыв.