Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Bash : « Aucun fichier ou dossier de ce type » alors que le fichier existe.. .

35 réponses
Avatar
Francois Lafont
Bonjour à tous,

Je suis confronté à un problème bien mystérieux que je vous soumets et
qui pourrait se résumer à ceci :

#---------------------------------------------
# cd /etc/se3/bin/
# ls -l n*
-rwx------ 1 root root 999994 30 mai 13:19 numlock_active_i386
# ./numlock_active_i386
-bash: ./numlock_active_i386: Aucun fichier ou dossier de ce type
# ./n*
-bash: ./numlock_active_i386: Aucun fichier ou dossier de ce type
# test -e ./numlock_active_i386 && echo Existe
Existe
#---------------------------------------------

Comme vous pouvez voir, je suis root et le fichier numlock_active_i386
existe bel et bien (la complétion automatique du nom avec la touche TAB
fonctionne très bien) et les droits sont corrects. Au départ, je me
disais que, peut-être, le nom du fichier contenait je ne sais quel
caractère non imprimable ou un truc dans le genre, mais ça ne semble pas
être le cas :

#---------------------------------------------
# \ls n* | od -c
0000000 n u m l o c k _ a c t i v e _ i
0000020 3 8 6 \n
#---------------------------------------------

La partition qui contient le répertoire /etc/se3/bin/ est montée tout
simplement monté sur / et j'ai :

#---------------------------------------------
# mount | grep 'on / '
/dev/sda5 on / type ext4 (rw,errors=remount-ro)
#---------------------------------------------

Bref, au niveau de la partition je n'ai pas l'impression que ça soit
particulièrement exotique.

Autre information : la machine est une Debian Squeeze 64 bits.

#---------------------------------------------
# uname -a
Linux smm1-03 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64
GNU/Linux
#---------------------------------------------

Enfin, pour être parfaitement complet, il faut que je vous parle du
fichier en question (numlock_active_i386) car c'est un peu particulier.
Peut-être que ça n'a rien à voir avec le problème mais dans le doute je
vous livre ce qui suit. C'est peut-être important.

Le fichier numlock_active_i386 est en fait le résultat d'une compilation
d'un tout petit programme en langage C. En l'occurrence, ce programme là :

//------------------------------------------------
#include <X11/XKBlib.h>
#include <X11/extensions/XKB.h>
#include <X11/keysym.h>

int main () {
Display *disp = XOpenDisplay(NULL);
if(disp == NULL) return 1;
unsigned int nl_mask = XkbKeysymToModifiers(disp, XK_Num_Lock);
XkbLockModifiers(disp, XkbUseCoreKbd, nl_mask, nl_mask);
XCloseDisplay(disp);
return 0;
}
//------------------------------------------------

Ce programme (trouvé sur le Web car je suis nul en C) permet de simuler
l'appui sur la touche "VerrNum" afin d'activer le pavé numérique. Sur
Debian, il y a le paquet « numlockx » qui fournit la commande du même
nom qui fait exactement cela. Mais lorsque la commande numlockx est
lancée *avant* qu'un utilisateur ouvre une session, c'est-à-dire
typiquement au moment où la fenêtre de connexion du display manager
s'affiche, celle-ci ne fonctionne pas (il semble que ça soit un bug
connu et signalé à plusieurs reprises). C'est pourquoi, après des
recherches sur le Web, j'étais tombé sur le programme ci-dessus qui lui
fonctionne aussi au moment de l'affichage de la fenêtre de connexion.

Sur une Squeeze 32 bits, je l'avais compilé comme ceci, sans erreur
(auparavant il a fallu que j'installe le paquet « libx11-dev »)

$ gcc -l X11 numlock_active_i386.c -o numlock_active_i386

Mais le souci, c'est que j'obtenais un fichier qui ne marchait que sur
des 32 bits et au niveau des bibliothèques partagées (attention je suis
nul en C alors mes explications sont sans doute un peu foireuses) ça
coinçait quand je cherchait à lancer le binaire sur une 64 bits. Du
coup, j'ai *essayé* de faire une compilation qui encapsule toutes les
bibliothèques partagées nécessaires dans le binaire afin que celui-ci
soit « standalone » et qu'il marche aussi bien sur un 32 bits qu'un 64
bits.n Du coup, sur ma Squeeze 32 bits, j'ai fait ça :

$ gcc -l X11 -c numlock_active_i386.c -o numlock_active_i386.o

Ensuite, j'ai tenté ça :

gcc numlock_active_i386.o -o numlock_active_i386

Et en fonction des messages d'erreur un peu évocateur, j'ai ajouté des
bibliothèques jusqu'à que ceci me donne une compilation sans erreur :

gcc numlock_active_i386.o /usr/lib/libX11.a /usr/lib/libxcb.a \
/usr/lib/libXau.a /usr/lib/libXdmcp.a -o numlock_active_i386

Voilà, j'espère avoir donné toutes les informations nécessaires. Si ce
n'est pas le cas, n'hésitez pas à me demander.

Bref, pourquoi diable le shell me dit que le fichier n'existe pas alors
que celui-ci existe ?

Merci d'avance pour votre aide.



--
François Lafont

10 réponses

1 2 3 4
Avatar
Francois Lafont
Le 30/05/2012 21:54, Alex F. a écrit :

#------------------------------------------
function est_64_bits ()
{
...
}

if est_64_bits; then
# On lance le binaire version 64 bits.
/mnt/partage/numlock_active_64_bits
else
# Sinon, on est a priori sur un hôte 32 bits,
# alors on lance le binaire version 32 bits.
/mnt/partage/numlock_active_32_bits
fi
#------------------------------------------

Mais dans ce cas, que faudrait-il que je mette exactement dans le corps
de la fonction est_64_bits ?




Sans la fonction, un test de ce genre devrait suffire:

#!/bin/sh

if [ "$(uname -m)" = "x86_64" ]; then
/mnt/partage/numlock_active_64_bits
else
/mnt/partage/numlock_active_32_bits

fi



Mais est-ce que j'ai la garantie sur une 64 bits d'avoir toujours [
"$(uname -m)" = "x86_64" ] ? Parce que sur une 32 bits, je pensais que
j'aurais toujours [ "$(uname -m)" = "i386" ] et je m'aperçoit sur une
machine que j'obtiens "i686" ?


--
François Lafont
Avatar
Arnaud Gomes-do-Vale
Francois Lafont writes:

Je vois, mais cela suppose devoir modifier le PATH de toutes les
machines alors ?



Oui. Si je peux me permettre, gérer n machines (n>=2) sans outil de
gestion de config, ça expose très vite à ce genre de soucis. ;-)

$ arch
i686

Perso, je m'attendais à trouver "i386" (qui pour moi veut « 32 bits »).
C'est normal ?



Oui, c'est «uname -i» qui devrait renvoyer i386. Sauf que manifestement
les noyaux Debian ne sont pas compilés comme les autres, «uname -i» et
«uname -p» renvoient aussi «unknown» sur ma station 64 bits.

Est-ce qu'au moins, sur une machine installée avec l'iso
debian-509-i386-netinst.iso, j'ai la garantie d'avoir toujours ceci ?

-------------------------------------------------
$ arch
x86_64
-------------------------------------------------



Avec une ISO 32 bits ? Je n'ai pas de machine avec ce genre de config
sous la main pour regarder mais ça m'étonnerait.

--
Arnaud
http://blogs.glou.org/arnaud/
Avatar
Luc.Habert.00__arjf
Francois Lafont :

/usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/libX11.a(xim_trans.o):
In function `_XimXTransSocketUNIXConnect':
(.text+0xcda): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking



J'imagine que que le getaddrinfo de la libc.a fait un dlopen (fonction qui
permet de charger une lib dynamique spécifiée par le programme, c'est plus
souple que les dépendances gravées dans les métadonnées de l'exe) de la
libc.so (ou plutôt libresolv.so). J'hallucine complètement. Je ne sais pas
si il y a un workaround. Sinon, ça semble vouloir dire que ça ne va pas
marcher.
Avatar
Francois Lafont
Le 30/05/2012 23:03, Luc Habert a écrit :

/usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/libX11.a(xim_trans.o):
In function `_XimXTransSocketUNIXConnect':
(.text+0xcda): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking



J'imagine que que le getaddrinfo de la libc.a fait un dlopen (fonction qui
permet de charger une lib dynamique spécifiée par le programme, c'est plus
souple que les dépendances gravées dans les métadonnées de l'exe) de la
libc.so (ou plutôt libresolv.so). J'hallucine complètement. Je ne sais pas
si il y a un workaround. Sinon, ça semble vouloir dire que ça ne va pas
marcher.



J'avoue ne pas avoir tout compris si ce n'est que ça semble un peu
compliqué tout ça. Du coup, je crois que je vais m'orienter vers
l'option « 2 binaires distincts » l'un pour 32 bits, l'autre pour 64
bits qui ne seront donc pas « standalone » et je ferai alors un truc
comme ça :

#-------------------------------------------
if [ "$(uname -m)" = "x86_64" ]; then
/mnt/partage/numlock_active_64_bits
else
/mnt/partage/numlock_active_32_bits

fi
#-------------------------------------------

Non ?


--
François Lafont
Avatar
Philippe Naudin
Le mer. 30 mai 2012 22:50:03 CEST, Francois Lafont a écrit:

Le 30/05/2012 21:54, Alex F. a écrit :

>> #------------------------------------------
>> function est_64_bits ()
>> {
>> ...
>> }
>>
>> if est_64_bits; then
>> # On lance le binaire version 64 bits.
>> /mnt/partage/numlock_active_64_bits
>> else
>> # Sinon, on est a priori sur un hôte 32 bits,
>> # alors on lance le binaire version 32 bits.
>> /mnt/partage/numlock_active_32_bits
>> fi
>> #------------------------------------------
>>
>> Mais dans ce cas, que faudrait-il que je mette exactement dans le corps
>> de la fonction est_64_bits ?
>>
>
> Sans la fonction, un test de ce genre devrait suffire:
>
> #!/bin/sh
>
> if [ "$(uname -m)" = "x86_64" ]; then
> /mnt/partage/numlock_active_64_bits
> else
> /mnt/partage/numlock_active_32_bits
>
> fi

Mais est-ce que j'ai la garantie sur une 64 bits d'avoir toujours [
"$(uname -m)" = "x86_64" ] ? Parce que sur une 32 bits, je pensais que
j'aurais toujours [ "$(uname -m)" = "i386" ] et je m'aperçoit sur une
machine que j'obtiens "i686" ?



À ma connaissance, ce sera toujours x86_64 sur un système Intel 64
bits. Ça peut être différentes choses sur un 32 bits :
$ man arch
arch is deprecated command since release util-linux 2.13. Use uname -m.

On current Linux systems, arch prints things such as "i386", "i486",
"i586", "alpha", "sparc", "arm", "m68k", "mips", "ppc".

À ta place, je ferais deux binaires (numlock_active_x86_64 et
numlock_active_i386) plus des liens symboliques pour les autres
variantes en 32 bits et j'invoquerais ça comme
numlock_active_$(uname -m).

Moins élégant qu'un binaire statique universel, mais beaucoup plus
simple à mettre en oeuvre, et il n'y a rien à modifier sur les postes
de travail.

--
Philippe Naudin
Avatar
Arnaud Gomes-do-Vale
Francois Lafont writes:

Est-ce qu'au moins, sur une machine installée avec l'iso
*debian-6.0.5-amd64-netinst.iso*, j'ai la garantie d'avoir toujours ceci ?

-------------------------------------------------
$ arch
x86_64
-------------------------------------------------



À ma connaissance oui.

--
Arnaud
http://blogs.glou.org/arnaud/
Avatar
Erwan David
(Luc Habert) écrivait :

Francois Lafont :

/usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/libX11.a(xim_trans.o):
In function `_XimXTransSocketUNIXConnect':
(.text+0xcda): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking



J'imagine que que le getaddrinfo de la libc.a fait un dlopen (fonction qui
permet de charger une lib dynamique spécifiée par le programme, c'est plus
souple que les dépendances gravées dans les métadonnées de l'exe) de la
libc.so (ou plutôt libresolv.so). J'hallucine complètement. Je ne sais pas
si il y a un workaround. Sinon, ça semble vouloir dire que ça ne va pas
marcher.



C'est pour nss qu'il faut des libs dynamiques, même en statique. Pour
interroger le DNS ou passer par des fichiers/NIS/LDAP, etc.

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Avatar
Nicolas George
Luc Habert, dans le message <jq61u9$au$, a écrit :
J'imagine que que le getaddrinfo de la libc.a fait un dlopen (fonction qui
permet de charger une lib dynamique spécifiée par le programme, c'est plus
souple que les dépendances gravées dans les métadonnées de l'exe) de la
libc.so (ou plutôt libresolv.so). J'hallucine complètement. Je ne sais pas
si il y a un workaround. Sinon, ça semble vouloir dire que ça ne va pas
marcher.



Quand je dis que la liaison statique n'est pas une bonne solution.
Avatar
moi-meme
Le Wed, 30 May 2012 18:55:15 +0200, Francois Lafont a écrit :

#include <X11/XKBlib.h>
#include <X11/extensions/XKB.h>
#include <X11/keysym.h>

int main () {
Display *disp = XOpenDisplay(NULL);
if(disp == NULL) return 1;
unsigned int nl_mask = XkbKeysymToModifiers(disp, XK_Num_Lock);
XkbLockModifiers(disp, XkbUseCoreKbd, nl_mask, nl_mask);
XCloseDisplay(disp);
return 0;
}.



tu n'as pas eu le "patch" en entier
il y a à la fin :
/*
dep : libx11-dev
compil : gcc numlockx.c -lX11 -o /usr/bin/numlockx
Les NOUVEAUX paquets suivants seront installés :
libpthread-stubs0 libpthread-stubs0-dev libx11-dev libxau-dev libxcb1-
dev libxdmcp-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev
xorg-sgml-doctools xtrans-dev
*/

je suis d'accord avec la fin du "patch". Il faut ajouter des paquets.

Le patch fonctionne très bien.
Avatar
Francois Lafont
Le 31/05/2012 08:07, moi-meme a écrit :
Le Wed, 30 May 2012 18:55:15 +0200, Francois Lafont a écrit :

#include <X11/XKBlib.h>
#include <X11/extensions/XKB.h>
#include <X11/keysym.h>

int main () {
Display *disp = XOpenDisplay(NULL);
if(disp == NULL) return 1;
unsigned int nl_mask = XkbKeysymToModifiers(disp, XK_Num_Lock);
XkbLockModifiers(disp, XkbUseCoreKbd, nl_mask, nl_mask);
XCloseDisplay(disp);
return 0;
}.



tu n'as pas eu le "patch" en entier
il y a à la fin :
/*
dep : libx11-dev



Ça j'avais eu. On est d'accord que l'installation du paquet libx11-dev
es nécessaire seulement sur la machine où on compile, c'est bien ça ?

compil : gcc numlockx.c -lX11 -o /usr/bin/numlockx



Ah, ça et ce qui suit, ça n'était pas indiqué sur la page Web que
j'avais trouvée (je ne sais plus laquelle). Il faut donc que je me
procure le code source de numlockx.

Les NOUVEAUX paquets suivants seront installés :
libpthread-stubs0 libpthread-stubs0-dev libx11-dev libxau-dev libxcb1-
dev libxdmcp-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev
xorg-sgml-doctools xtrans-dev



Concernant l'installation de ces paquts, il sont nécessaires :

1. seulement sur la machine où l'on fait la compilation ?
2. seulement sur la machine hôte qui exécutera le binaire ?
3. sur les deux machines ?

Le patch fonctionne très bien.



Avec le mini code que j'avais donné dans mon premier message, il me
semble que j'obtiens aussi un truc qui marche bien, pour peu qu'on
utilise un binaire adapté à l'architecture de l'hôte. Mais effectivement
autant faire comme tu indiques. Simplement j'ai un doute sur
l'installation des paquets, s'ils doivent avoir lieu uniquement sur la
machine où on compile ou non ?

Merci pour l'information en tout cas.


--
François Lafont
1 2 3 4