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 devrait au moins vérifier si le fichier a des droits d'exécution, est 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 en 32 bits, ...) que le système actuel.
Réponses
Trop de publicités?Pour tester si un fichier lui-même a le bit ACL_EXECUTE
défini dans l'un des ensembles de permissions (utilisateur, groupe, autres) indépendamment de l'endroit où il se trouve, c'est-à-dire même sur un tmpfs avec l'option noexec, utilisez stat -c '%A'
pour obtenir la chaîne de permission, puis vérifiez si elle contient au moins une lettre "x" :
if [[ "$(stat -c '%A' 'mon_fichier_exec')" == *'x'* ]] ; then
echo 'A la permission d'exécution pour quelqu'un'
fi
La partie droite de la comparaison peut être modifiée pour s'adapter à des cas plus spécifiques, comme *x*x*x*
pour vérifier si tous les types d'utilisateurs devraient être en mesure d'exécuter le fichier lorsqu'il est placé sur un volume monté avec l'option exec.
Cela peut ne pas être si évident, mais parfois il est nécessaire de tester l'exécutable pour l'appeler de manière appropriée sans processus shell externe :
fonction tkl_is_file_os_exec()
{
[[ ! -x "$1" ]] && return 255
local exec_header_bytes
case "$OSTYPE" in
cygwin* | msys* | mingw*)
# ATTENTION :
# La version de bash 3.2+ peut nécessiter un chemin de fichier avec l'extension,
# sinon une erreur sera lancée : `bash: ...: Aucun fichier ou dossier de ce type`.
# Nous faisons donc une supposition pour éviter l'erreur.
#
{
read -r -n 4 exec_header_bytes 2> /dev/null < "$1" ||
{
[[ -x "${1%.exe}.exe" ]] && read -r -n 4 exec_header_bytes 2> /dev/null < "${1%.exe}.exe"
} ||
{
[[ -x "${1%.com}.com" ]] && read -r -n 4 exec_header_bytes 2> /dev/null < "${1%.com}.com"
}
} &&
if [[ "${exec_header_bytes:0:3}" == $'MZ\x90' ]]; then
# $'MZ\x90\00' pour bash version 3.2.42+
# $'MZ\x90\03' pour bash version 4.0+
[[ "${exec_header_bytes:3:1}" == $'\x00' || "${exec_header_bytes:3:1}" == $'\x03' ]] && return 0
fi
;;
*)
read -r -n 4 exec_header_bytes < "$1"
[[ "$exec_header_bytes" == $'\x7fELF' ]] && return 0
;;
esac
return 1
}
# exécute le script dans le processus shell en cas de script shell, sinon exécute comme d'habitude
fonction tkl_exec_inproc()
{
if tkl_is_file_os_exec "$1"; then
"$@"
else
. "$@"
fi
return $?
}
myscript.sh:
#!/bin/bash
echo 123
return 123
Sous Cygwin:
> tkl_exec_inproc /cygdrive/c/Windows/system32/cmd.exe /c 'echo 123'
123
> tkl_exec_inproc /cygdrive/c/Windows/system32/chcp.com 65001
Active code page: 65001
> tkl_exec_inproc ./myscript.sh
123
> echo $?
123
Sous Linux:
> tkl_exec_inproc /bin/bash -c 'echo 123'
123
> tkl_exec_inproc ./myscript.sh
123
> echo $?
123
- Réponses précédentes
- Plus de réponses
1 votes
Je penserais soit ls -la [nom du fichier] ou stat [nom du fichier]
1 votes
Ni ls -la ni stat ne donnent d'informations sur l'architecture prise en charge, ce qui est en réalité la partie de la question qui m'intéresse le plus. J'ai rencontré une erreur parce qu'un exécutable n'avait pas été compilé pour mon architecture, et j'aimerais créer un script pour éviter cela à l'avenir.
2 votes
@bob: Avez-vous essayé de vérifier la sortie de
file
exécutée sur ces fichiers?1 votes
@FatalError Comment pourrais-je analyser la sortie du fichier pour vérifier si l'exécutable est conforme à mon architecture ?
0 votes
Vérifier : opérateurs de test de fichiers