Нет, главным образом по той причине, что не требуется, чтобы системы соответствовали по умолчанию или соответствовали только стандарту POSIX (исключение любого другого стандарта ).
Например, Solaris (, сертифицированная совместимая система ), выбрала обратную совместимость для своих утилит в /bin
, что объясняет, почему они ведут себя загадочным образом, и предоставляют совместимые с POSIX -утилиты в разных местах (/usr/xpg4/bin
. ], /usr/xpg6/bin
... для различных версий XPG (, теперь объединенных со стандартом POSIX ), которые фактически являются частью необязательных компонентов в Solaris ).
Даже sh
не обязательно будет в /bin
. В Solaris /bin/sh
раньше была оболочкой Bourne (, поэтому она не совместима с POSIX )до Solaris 10, а теперь ksh93 в Solaris 11 (все еще не полностью совместима с POSIX, но на практике в большей степени, чем /usr/xpg4/bin/sh
).
Из С,вы можете использовать exec*p()
и предположить, что вы находитесь в среде POSIX (, в частности, в отношении PATH
переменной среды ).
Вы также можете установить переменную окружения PATH
#define _POSIX_C_SOURCE=200809L /* before any #include */
...
confstr(_CS_PATH, buf, sizeof(buf)); /* maybe append the original
* PATH if need be */
setenv("PATH", buf, 1);
exec*p("ps"...);
Или вы можете определить во время сборки путь к утилитам POSIX, которые вы хотите запустить (, имея в виду, что в некоторых системах, таких как системы GNU, вам потребуются дополнительные шаги, такие как установка POSIXLY_CORRECT
переменной для обеспечения соответствия ).
Вы также можете попробовать:
execlp("sh", "sh", "-c", "PATH=`getconf PATH`${PATH+:$PATH};export PATH;"
"unset IFS;shift \"$1\";"
"exec ${1+\"$@\"}", "2", "1", "ps", "-A"...);
В надежде, что в $PATH
есть sh
, что он похож на -Борна, что также есть getconf
и что он подходит для интересующей вас версии POSIX.
for x in $(find …)
не работает с именами файлов, содержащими пробелы (общие )или подстановочные знаки (несколько необычные). Никогда не анализируйте вывод find
. Используйте -exec
.
Zsh 'szmv
удобен для массового переименования.
Давайте создадим команду zmv, которая будет делать то, что вы хотите. Во-первых, давайте построим шаблон поиска:
autoload zmv
zmv -C -o -a -n -Q '(*/)#^*.*(.)' …
-C
заставляет файлы копироваться, а не перемещаться. -o -a
переходит от -a
к cp
. -n
означает не действовать, просто напечатать то, что будет сделано. Удалите его, как только вы будете счастливы. Замените его на -v
, если вы хотите действовать, но также печатать то, что делается. -Q
включает квалификаторы glob в шаблоне. (*/)#
соответствует нулю или более каталогам. Он использует оператор глобуса#
(extended_glob
, который всегда включен в zmv ). ^*.*
использует оператор glob ^
для сопоставления файлов без .
в их имени. (.)
— это квалификатор glob, который ограничивает совпадения с обычными файлами. …
будет заменен текстом замены. Это может использовать $f
для ссылки на исходное имя. zmv
вычисляет все замещающие имена перед выполнением какой-либо замены и выдает сообщение, если какое-либо замещающее имя уже существует или возникают конфликты. Файлы, для которых замещающее имя идентично исходному, пропускаются.
Теперь создадим замещающий текст. Мы будем использовать множество расширений параметров .
file
добавочный номер:$(file --extension --brief -- $f)
.
для подготовки к замене:$(echo -n.; file --extension --brief -- $f)
${:-.$(…)}
.)${$(echo -n.; file --extension --brief -- $f)%%/*}
???
,отказаться от (заменить .
или .???
пустой строкой):${${$(echo -n.; file --extension --brief -- $f)%%/*}:#.(|\?\?\?)}
$f
(исходному имени ). Если то, что мы добавляем, пусто, файл останется нетронутым. Результирующая команда:
zmv -C -o -a -n -Q '(*/)#^*.*(.)' '$f${${$(echo -n.; file --extension --brief -- $f)%%/*}:#.(|\?\?\?)}'
Это немного загадочно, и вы можете предпочесть поместить код для генерации замены в функцию и использовать zmv … '$(add_extension $f)'
.
Я думаю, что наиболее эффективным способом является сравнение mime-типов -файла с базой данных, расположенной по адресу /usr/share/mime/globs
.
application/x-mswinurl:*.url
text/x-mrml:*.mrl
text/x-erlang:*.erl
audio/x-pn-audibleaudio:*.aa
application/x-bzip-compressed-tar:*.tbz2
application/x-netshow-channel:*.nsc
application/x-hdf:*.h4
application/pgp-keys:*.key
text/x-idl:*.idl
text/x-chdr:*.h
application/vnd.ms-powerpoint.presentation.macroEnabled.12:*.pptm
application/vnd.ms-powerpoint.presentation.macroEnabled.12:*.pptm
application/vnd.visio:*.vsd
application/x-hdf:*.h5
video/vnd.mpegurl:*.m4u
text/x-erlang
, он указывает Linux идентифицировать все файлы *.
как Erlang с расширением .erl
[glob], поэтому -->*.erl
/etc/magic
поэтому запустив команду:
mimetype -bM file
b
аргумент в пользу просто покажу вамtype-app/extension
(кратко)
M
означает Магия — это способ, с помощью которого Linux проверяет файл в байтовом, шестнадцатеричном, двоичном коде, чтобы убедиться, что файлы действительно являются теми, за кого себя выдают.
mimetype не возвращает /jpg/png/webp
возвращает только один тип, и он короче, чемfile --mime-type file
Возвращает:
image/webp
mimetype
лучше всего работает с двоичными файлами , такими как PDF-файлы, изображения, видео. Это потому, что он может проверять двоичный файл, вместо этого text plain
- это просто, и вам нужно с чем-то идентифицировать, а это сложнее, поэтому текстовые редакторы могут реконизировать разные языки программирования, ему нужна помощь пользователя и язык сервера для каждого языка программирования.
tree -FIi '*.*' | grep -v /$
F
для добавления /
[косая черта] к каталогам, например, folder
→folder/
I
— выбор противоположного шаблону *.*
[это означает выбор всех файлов с расширением],так что противоположное не является расширением i
— удалить пробелы из вывода дерева grep -v
означает выбор реверса, поэтому вы добавляете аргумент -F /
к команде tree в начале, чтобы вы могли удалять каталоги и получать только файлы с помощью /$
. Подробнее здесь MIME-типы