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.
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
).
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.
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 ]]
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.
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
.
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