Подтвердить что ты не робот

Проверьте, является ли файл исполняемым

Мне интересно, что самый простой способ проверить, является ли программа исполняемой с помощью bash, без ее выполнения? Он должен по крайней мере проверить, имеет ли файл права выполнения и имеет одну и ту же архитектуру (например, не исполняемый файл Windows или другую неподдерживаемую архитектуру, а не 64 бита, если система 32 бита,...) в качестве текущей системы.

4b9b3361

Ответ 1

Взгляните на различные операторы test (это для самой тестовой команды, но встроенные тесты BASH и TCSH больше или менее того же).

Вы заметите, что -x FILE говорит, что ФАЙЛ существует, и предоставляется разрешение на выполнение (или поиск).

BASH, Bourne, Ksh, Zsh Script

if [[ -x "$file" ]]
then
    echo "File '$file' is executable"
else
    echo "File '$file' is not executable or found"
fi

TCSH или CSH Script:

if ( -x "$file" ) then
    echo "File '$file' is executable"
else
    echo "File '$file' is not executable or found"
endif

Чтобы определить тип файла, попробуйте file. Вы можете разобрать вывод, чтобы посмотреть, какой тип файла он имеет. Word 'o Предупреждение: Иногда file возвращает более одной строки. Вот что происходит на моем Mac:

$ file /bin/ls    
/bin/ls: Mach-O universal binary with 2 architectures
/bin/ls (for architecture x86_64):  Mach-O 64-bit executable x86_64
/bin/ls (for architecture i386):    Mach-O executable i386

Команда file возвращает разные выходные данные в зависимости от ОС. Однако слово executable будет в исполняемых программах, и обычно архитектура тоже появится.

Сравните приведенное выше с тем, что я получаю в своем ящике Linux:

$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), stripped

И окно Solaris:

$ file /bin/ls
/bin/ls:        ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped

Во всех трех случаях вы увидите слово executable и архитектуру (x86-64, i386 или SPARC с помощью 32-bit).


Добавление

Большое спасибо, это похоже на путь. Прежде чем отметить это как свой ответ, можете ли вы рассказать мне о том, какую проверку оболочки script мне нужно выполнить (например, какой синтаксический анализ) на "файл", чтобы проверить, могу ли я выполнить программу? Если такой тест слишком сложно сделать на общем основании, я бы хотя бы хотел проверить, является ли он исполняемым linux или osX (Mach-O)

Сверху моей головы вы можете сделать что-то вроде этого в BASH:

if [ -x "$file" ] && file "$file" | grep -q "Mach-O"
then
    echo "This is an executable Mac file"
elif [ -x "$file" ] && file "$file" | grep -q "GNU/Linux"
then
    echo "This is an executable Linux File"
elif [ -x "$file" ] && file "$file" | grep q "shell script"
then
    echo "This is an executable Shell Script"
elif [ -x "$file" ]
then
    echo "This file is merely marked executable, but what type is a mystery"
else
    echo "This file isn't even marked as being executable"
fi

В принципе, я запускаю тест, а затем, если это успешно, я делаю grep на выходе команды file. grep -q означает, что печать не выводится, но используйте код выхода grep, чтобы узнать, нашел ли я строку. Если ваша система не принимает grep -q, вы можете попробовать grep "regex" > /dev/null 2>&1.

Опять же, вывод команды file может отличаться от системы к системе, поэтому вам нужно будет убедиться, что они будут работать в вашей системе. Кроме того, я проверяю исполняемый бит. Если файл является двоичным исполняемым файлом, но исполняемый бит не включен, я скажу, что он не является исполняемым. Возможно, это не то, что вы хотите.

Ответ 2

Кажется, никто не заметил, что оператор -x не отличается файлом с каталогом.

Чтобы точно проверить исполняемый файл, вы можете использовать [[ -f SomeFile && -x SomeFile ]]

Ответ 3

Также кажется, что никто не заметил -x оператора на символических ссылках. Символьная ссылка (цепочка) на обычный файл (не классифицируется как исполняемый файл) не проходит тест.

Ответ 4

Тестирование файлов, каталогов и символических ссылок

Решения, приведенные здесь, не работают ни на каталогах, ни на символических ссылках (или на обоих). В Linux вы можете тестировать файлы, каталоги и символические ссылки с помощью:

if [[ -f "$file" && -x $(realpath "$file") ]]; then .... fi

В OS X вы должны быть в состоянии установить coreutils вместе с homebrew и использовать grealpath.

Определение функции isexec

Вы можете определить функцию для удобства:

isexec() {
    if [[ -f "$1" && -x $(realpath "$1") ]]; then
        true;
    else
        false;
    fi;
}

Или просто

isexec() { [[ -f "$1" && -x $(realpath "$1") ]]; }

Затем вы можете проверить с помощью:

if 'isexec "$file"'; then ... fi