Узнать расширение исполняемых файлов?

Как сказано многие время на этом сайте, оставляя переменное расширение (как в $var) или замена команды (как в `cmd` или $(cmd)) (или арифметическое расширение (как в $((11 * 11))) в большинстве оболочек), закрыл кавычки в оболочках Границы/POSIX, split+glob оператор.

Содержание $var или вывод cmd (без запаздывающих символов новой строки), разделяется согласно текущему значению $IFS специальная переменная (который по умолчанию содержит SPC, ВКЛАДКУ и символы NL (и NUL в zsh)) и каждое слово, получающееся из того разделения, подвергается поколению имени файла, также известному как globbing.

Например, если find ouputs ./foo bar.pdf\n./*foo*\tbar.pdf\n (\t значение ВКЛАДКИ и \n NL), со значением по умолчанию $IFS, замена команды расширится до ./foo bar.pdf\n./*foo*\tbar.pdf (запаздывание удаленной новой строки), и затем быть разделенным на ./foo, bar.pdf, ./*foo*, и foo.pdf и ./*foo* то, которое является подстановочным шаблоном, будет расширено в столько же аргументов, сколько существуют нескрытые файлы в текущем каталоге, имя которого содержит foo.

Если Вы хотите разделить на символах новой строки только, необходимо установить $IFS к новой строке только:

IFS='
'

Если Вы не хотите, чтобы подстановочные шаблоны были расширены, необходимо отключить его с

set -f

Однако обратите внимание, что новая строка является столь же допустимым символом как любой в имени файла, так в более общем плане, find -print вывод не может быть выполнен последующую обработку надежно.

Вывод как:

./a.pdf
./b.pdf

любое средство a.pdf и b.pdf файлы в текущем каталоге или названный файл b.pdf в a.pdf\n. каталог.

Некоторые find реализации как GNU find (где это произошло из), имеют a -print0 предикат для вывода имени файла, сопровождаемого символом NUL вместо символа NL. Со стандартом find, можно использовать -exec printf '%s\0' {} + с тем же результатом. NUL является единственным символом, который не может произойти в имени файла.

Однако zsh единственная оболочка, которая может сохранить символ NUL в его переменных (как $IFS символ), таким образом:

IFS=$'\0'
for i in `find ... -print0`; do
  ...
done

(никакая потребность в set -f в zsh с тех пор zsh не делает globbing на замену команды), будет работать в zsh но не в других оболочках.

Лучше всего, и портативно, должен иметь find назовите команды, Вы хотите работать на тех файлах. Поскольку @Gnouc предлагает:

find . -name '*.pdf' -exec the command {} \;

При необходимости в чем-нибудь более сложные операторы оболочки вовлечения можно все еще сделать вещи как:

find . -name '*.pdf' -exec sh -c '
  for i do
    something complex with "$i"
  done' sh {} +

С zsh или bash, можно также сделать:

find . -name '*.pdf' -print0 |
  while IFS= read -r -d '' file; do
    whatever with "$file"
  done

Однако обратите внимание, что stdin в цикле затронут.

zsh (с 1990) имеет большую часть функциональности find включенный в его globbing возможности через синтаксис, где можно указать любой уровень подкаталогов ((*/)# синтаксис или его более простая форма **/) и спецификаторы globbing (которые являются кулоном -type f, -mtime, -perm... в find).

**/ часть этого была скопирована ksh93 в 2003, fish в 2005, bash в 2009 и tcsh в 2010 (хотя tcsh также скопированный ***/ часть). И все они не включают его по умолчанию. К сожалению, отметьте это оба bash и fish ** действительно следуйте за символьными ссылками на каталоги (как -L/-follow в find, или *** в zsh или tcsh).

В тех оболочках можно найти pdf файлы на любом уровне подкаталогов, не имея необходимость полагаться find, но отметьте тот протест выше о fish и bash, и только zsh имеет globbing спецификаторы.

Так, например, zsh эквивалентный из:

find . -name '*.pdf' -type f -exec ls -ld {} +

был бы:

ls -ld ./**/*.pdf(D.)

В то время как с bash, необходимо было бы сделать что-то как:

shopt -s failglob
shopt -s globstar
files=(./**/*.pdf) &&
  for i do
    [ -f "$i" ] && ! [ -L "$i" ] && set -- "$i" "$@"
    shift
  done && ls -ld "$@"
5
04.07.2014, 02:01
2 ответа

Тест выполняется путем компиляции небольшой куклы на Си и проверки того, как компилятор называет выходной файл.

Следующий пример - упрощенная версия того, что configure делает

#!/bin/sh

cat << EOT > dummy.c
int main(int argc, char ** argv) {
    return 0;
}
EOT

gcc -o dummy dummy.c

if [ -f dummy.exe ] ; then
  # exe
fi

Я бы предложил использовать autoconf для генерации скрипта конфигурации и использовать его для своих целей.

5
27.01.2020, 20:40

Это даст вам расширение файла:

FILENAME=/tmp/testfile.exe
echo "${FILENAME##*.}"

result:

exe
-1
27.01.2020, 20:40

Теги

Похожие вопросы