web-dev-qa-db-fra.com

Vérifier si un fichier est exécutable

Je me demande quel est le moyen le plus simple de vérifier si un programme est exécutable avec bash, sans l'exécuter. Il convient au moins de vérifier si le fichier dispose des droits d’exécution et de la même architecture (par exemple, pas un exécutable Windows ou une autre architecture non prise en charge, pas 64 bits si le système est à 32 bits, ...) en tant que système actuel.

62
bob

Examinez les différents opérateurs test (ceci concerne la commande de test elle-même, mais les tests intégrés BASH et TCSH sont plus ou moins identiques).

Vous remarquerez que -x FILE dit que FILE existe et que l’autorisation d’exécution (ou de recherche) est accordée.

BASH, Bourne, Ksh, Zsh Script

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

Script TCSH ou CSH:

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

Pour déterminer le type du fichier, essayez la commande file . Vous pouvez analyser la sortie pour voir exactement quel type de fichier il s'agit. Word 'o Attention: Parfois file renverra plus d'une ligne. Voici ce qui se passe sur mon 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

La commande file renvoie différents résultats en fonction du système d'exploitation. Cependant, le mot executable figurera dans des programmes exécutables et, généralement, l'architecture apparaîtra également.

Comparez ce qui précède à ce que je reçois sur ma machine 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

Et une boîte Solaris:

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

Dans les trois, vous verrez le mot executable et l’architecture (x86-64, i386 ou SPARC avec 32-bit).


Addenda

Merci beaucoup, cela semble être la voie à suivre. Avant de marquer ceci comme ma réponse, pouvez-vous s'il vous plaît me guider sur quel type de script je devrais vérifier Shell (c.-à-d. Quel type d'analyse) sur 'fichier' afin de vérifier si je peux exécuter un programme? Si un tel test est trop difficile à réaliser de manière générale, j'aimerais au moins vérifier s'il s'agit d'un exécutable linux ou osX (Mach-O)

De mémoire, vous pourriez faire quelque chose comme ça dans 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

Fondamentalement, je fais le test, puis si cela réussit, je fais un grep sur le résultat de la commande file. Le grep -q signifie que vous n'imprimez aucune sortie, mais utilisez le code de sortie de grep pour voir si j'ai trouvé la chaîne. Si votre système ne prend pas grep -q, tu peux essayer grep "regex" > /dev/null 2>&1.

Encore une fois, la sortie de la commande file peut varier d'un système à l'autre. Vous devrez donc vérifier que cela fonctionnera sur votre système. En outre, je vérifie le bit exécutable. Si un fichier est un exécutable binaire, mais que le bit exécutable n'est pas activé, je dirai que ce n'est pas exécutable. Cela peut ne pas être ce que vous voulez.

92
David W.

Il semble que personne n'ait remarqué que l'opérateur -x Ne diffère pas d'un fichier à l'autre.

Donc, pour vérifier précisément un fichier exécutable, vous pouvez utiliser [[ -f SomeFile && -x SomeFile ]]

10
osexp2003

Il semble également que personne n’a remarqué d’opérateur -x sur des liens symboliques. Un lien symbolique (chaîne) vers un fichier normal (non classé comme exécutable) échoue au test.

4
Dick Guertin

Test de fichiers, répertoires et liens symboliques

Les solutions données ici échouent sur des répertoires ou des liens symboliques (ou les deux). Sous Linux, vous pouvez tester des fichiers, des répertoires et des liens symboliques avec:

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

Sous OS X, vous devriez pouvoir installer coreutils avec homebrew et utiliser grealpath.

Définir une fonction isexec

Vous pouvez définir une fonction pour plus de commodité:

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

Ou simplement

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

Ensuite, vous pouvez tester en utilisant:

if `isexec "$file"`; then ... fi
1
pyrocrasty