22 votes

Erreurs de la commande whatis. Impossible de reconstruire la base de données avec makewhatis ?

Comment puis-je mettre à jour le whatis base de données ?

$ sudo /usr/libexec/makewhatis
Password:
makewhatis: /usr/share/man/whatis.tmp: Read-only file system

Je pense que le fait de pouvoir mettre à jour cette base de données résoudra un autre problème que j'ai. Mon chemin vers la découverte est le suivant...

J'ai récemment commencé à remarquer que les complétions des coquilles de poisson étaient fâcheusement lentes sur ma machine, peut-être peu après la mise à niveau vers Catalina.

J'ai fait un peu de profilage avec fish -d5 et a remarqué que la majorité du temps était consacré à la apropos commande. J'ai fait quelques lectures et j'ai appris que les outils apropos , whatis y makewhatis sont tous liés. Ils indexent les pages de manuel et les rendent consultables. Fish shell les utilise (correctement) pour proposer des compléments utiles.

Quand je cours whatis o apropos standalone, j'obtiens le résultat suivant :

$ whatis man
hugo-gen-man(1)          - Generate man pages for the Hugo CLI
groff_man(7)             - groff `man' macros to support generation of man pages
groffer(1)               - display groff files and man~pages on X and tty
man(1)                   - format and display the on-line manual pages
man.conf(5)              - configuration data for man
zshall(1)                - the Z shell meta-man page
xml2man(1)               - MPGL to mdoc (man page) translator
makewhatis: /usr/lib/./libgutenprint.2.dylib: No such file or directory
makewhatis: /usr/lib/libsasl2.2.0.1.dylib: Not a directory
makewhatis: /usr/lib/libldap.dylib: Not a directory
makewhatis: /usr/lib/libsqlite3.0.dylib: Not a directory
makewhatis: /usr/lib/libcom_err.dylib: Not a directory
...

Suivi par au moins 100 lignes supplémentaires des messages "Not a directory". Je crois que ce sont toutes ces lignes inutiles qui ralentissent les choses.

Alors j'ai pensé que peut-être je devais juste reconstruire le whatis (peut-être après la mise à jour de Catalina ?). Cependant, cela ne semble pas fonctionner :

$ sudo /usr/libexec/makewhatis
Password:
makewhatis: /usr/share/man/whatis.tmp: Read-only file system

Donc cette partie est un peu troublante. Comment puis-je reconstruire la base de données whatis ? J'ai l'impression que cela résoudra mes problèmes si j'arrive à le faire.

12voto

Hambly Points 149

Ce qui suit peut être utilisé comme solution de contournement pour la version MacOS 10.15.1 de la commande apropos, qui émet des plaintes de la forme suivante makewhatis: /usr/lib/lib … .dylib: Not a directory.

Tout d'abord, créez la solution de contournement script :

$ mkdir -p ~/workarounds
$ sed -e 66s@/usr/lib@@ /usr/bin/apropos > ~/workarounds/apropos.macos_10.15.1 
$ diff /usr/bin/apropos ~/workarounds/apropos.macos_10.15.1 
66c66
<     for d in /var/cache/man $manpath /usr/lib
---
>     for d in /var/cache/man $manpath 
$ chmod +x ~/workarounds/apropos.macos_10.15.1

Ensuite, ajoutez un alias à votre shell pour lui dire d'utiliser le contournement script, jusqu'à ce qu'une version plus récente du script canonique soit disponible.

Pour Zsh, vous pouvez utiliser la commande suivante :

$ /bin/cat <<END >> ~/.zshrc
# Workaround for broken apropos command.
alias apropos=~/workarounds/apropos.macos_10.15.1
END

Pour les autres shells tels que ksh ou bash, utilisez ~/.profile ou ~/.bash_profile, selon le cas.

Que fait la solution de contournement ?

Les requêtes Apropos (et les requêtes man -k) sont traitées par la commande /usr/bin/apropos script. Ce script recherche les fichiers de la base de données "whatis" dans tous les répertoires du chemin de man (voir man —path ), plus /var/cache/man y /usr/lib . Les contrôles pour /var/cache/man/whatis y /usr/lib/whatis semblent être là pour des raisons historiques, mais ces fichiers ne sont pas activement générés dans Mojave ou Catalina. De nombreuses personnes ont contribué aux différentes versions d'Unix au fil des ans, et beaucoup d'entre elles avaient de bonnes idées sur l'emplacement des différents types de fichiers. À un moment donné, quelqu'un a décidé que /usr/lib serait un bon endroit pour mettre un fichier whatis, et à un autre moment quelqu'un d'autre a pensé que /var/cache/man serait un bon endroit. D'autres ont pensé que l'endroit approprié serait les répertoires respectifs des pages de manuel. Différentes solutions qui semblaient appropriées à l'époque. L'apropos script a traditionnellement vérifié ces emplacements au cas où un fichier whatis était présent.

Depuis que les répertoires système de Catalina sont en lecture seule (une bonne décision), les fichiers de la base de données whatis ne peuvent plus être écrits dans des répertoires tels que /usr/share/man . Il existe différentes façons pour Apple de gérer cela, mais pour cette version, quelqu'un a décidé de modifier l'apropos script en lui faisant générer des résultats à la volée en appelant /usr/libexec/makewhatis.local pour tout répertoire de pages de manuel qui ne contient pas de fichier whatis.

Ce nouveau code à propos fonctionne bien pour les répertoires de pages de manuel actuels, et pour /var/cache/man (puisqu'elle n'existe pas), mais elle échoue pour /usr/lib . La solution de contournement détaillée ci-dessus élimine simplement /usr/lib de la liste des répertoires recherchés.

Pour terminer, fixez-vous un rappel dans un mois ou deux pour vérifier si Apple a corrigé le script. Si c'est le cas, supprimez vos solutions de contournement, en supprimant l'alias et la solution de contournement script.

3voto

TinkerBear Points 31

Je viens de tomber sur ça et j'ai cherché sur Google...

On dirait que "whatis" va soit parcourir les fichiers whatis générés, soit les générer à la volée vers le stdout. Ce que nous voyons est la sortie de "makewhatis" exécutée sur /usr/lib.

Vous obtiendrez les mêmes erreurs à partir de :

/usr/libexec/makewhatis -o /dev/fd/1 /usr/lib

/usr/lib n'est pas dans le manpath (sortie de "man --path") - il est ajouté explicitement par "whatis", mais pour quelle raison je n'en ai aucune idée. Il n'y a pas de pages de manuel ici, et makewhatis s'attend clairement à ce que tout ce qui se trouve dans un dossier de manuel soit un sous-répertoire.

Si nous pouvions éditer le script "whatis", nous pourrions le réparer. Mais on ne peut pas, parce que /usr/bin est en lecture seule.

Si nous pouvions générer un /usr/lib/whatis vide, les plaintes cesseraient. Mais nous ne pouvons pas le faire car /usr/lib est en lecture seule.

Il pourrait être possible de corriger /usr/libexec/makewhatis.local pour arrêter ce non-sens, mais il est en lecture seule.

Je dois faire des recherches pour voir s'il y a un moyen de monter le volume du système d'exploitation en lecture-écriture pendant un moment.

Sur une note connexe : Même si nous avons réussi à exécuter un "makewhatis", il ne générera pas /usr/lib/whatis, parce que /usr/lib n'est pas dans le chemin du man... donc il ne résoudra pas ce problème. Créer un /usr/lib/whatis vide est probablement l'option la plus facile et la plus sûre, si nous pouvons trouver comment.

2voto

Hambly Points 149

En ce qui concerne une solution qui générerait les fichiers whatis manquants :

La solution pour la mise à jour de la base de données "whatis" en /usr/share/man nécessite un correctif d'Apple. Ils doivent soit ajouter /usr/share/man à leur liste de liens fermes (similaire à la mise en œuvre pour les /usr/share/snmp ), ou ajouter une copie statique de l whatis sur le volume système.

Les liens fermes sont une nouvelle fonctionnalité de l'APFS, conçue pour prendre en charge la fusion de volumes en lecture-écriture avec des volumes système en lecture seule. À partir de la version Catalina, les fichiers du système d'exploitation de base sont conservés sur un volume en lecture seule, qui est ensuite fusionné avec un volume de données en lecture-écriture via l'utilisation de liens fermes. Sous MacOS version 10.15.1, /usr/share/man est uniquement présent sur le volume système en lecture seule. Vous pouvez ajouter une entrée pour /usr/share/man au volume de données en créant le répertoire /System/Volumes/Data/usr/share/man comme le montre la réponse de klanomath, mais il ne sera pas mappé sur le répertoire système (/usr/share/man) jusqu'à ce qu'un lien ferme correspondant soit créé.

Une liste des firmlinks actuels se trouve dans /usr/share/firmlinks . La documentation que j'ai pu trouver jusqu'à présent n'est pas claire quant à savoir si firmlinks est un fichier de référence, ou un fichier de configuration, mais il me semble que c'est un fichier de configuration qui est lu et utilisé dans le cadre des procédures de démarrage. En supposant qu'il s'agisse d'un fichier de configuration, vous pourriez théoriquement corriger le problème en ajoutant une entrée pour /usr/share/man dans le fichier.

Malheureusement, comme /usr/share/firmlinks est logé dans le volume système en lecture seule, vous ne pouvez pas le modifier en tant qu'utilisateur, ni même en tant que super-utilisateur. Même en mode mono-utilisateur, le montage du groupe de volumes système en mode lecture-écriture est empêché (ie : /sbin/mount -uw / ne fonctionne pas). Il est peut-être possible de monter le volume système en tant que lecteur secondaire sur un système secondaire, puis de procéder aux modifications, mais cela demande plus de temps d'expérimentation que ce que je suis prêt à faire.

En résumé, la sécurité améliorée de Catalina empêche la mise à jour de ce répertoire jusqu'à ce qu'Apple corrige le problème.

Les notes ci-dessus sont relatives à Catalina (MacOS v 10.15.1). Comme il s'agit d'un simple correctif, je pense que le problème sera bientôt corrigé.

2voto

Tim Points 21

Je viens de découvrir ce problème aujourd'hui et j'ai créé les alias suivants dans ~/.zshrc pour nettoyer la sortie de la commande :

alias apropos="apropos 2>/dev/null"
alias whatis="whatis 2>/dev/null"

Les alias suppriment les erreurs de la sortie en utilisant la redirection. L'interpréteur de commandes possède deux descripteurs de fichiers pour la sortie. La sortie standard est le descripteur de fichier 1 et la sortie d'erreur standard est le descripteur de fichier 2. Les erreurs générées par le script makewhatis.local script sont envoyées à la sortie d'erreur standard.

La redirection de la sortie d'erreur standard est effectuée en utilisant le descripteur de fichier stderr "2", l'opérateur de redirection de sortie ">", et le fichier de destination "/dev/null". Le fichier /dev/null est un objet spécial du système de fichiers qui rejette tout ce qui y est écrit. Avec les erreurs redirigées, seuls les résultats souhaités sont affichés.

1voto

klanomath Points 63400

Essayez celui-ci () :

  1. sudo mkdir /System/Volumes/Data/usr/share/man
  2. sudo /usr/libexec/makewhatis -o /System/Volumes/Data/usr/share/man/whatis
  3. user@host ~ % cd /System/Volumes/Data/usr/share/man/ user@host man % lsl total 384 drwxr-xr-x 3 root wheel - 96 Nov 3 01:33 . drwxr-xr-x 4 root wheel sunlnk 128 Nov 3 01:32 .. -rw-r--r-- 1 root wheel - 160236 Nov 3 01:33 whatis

    lsl est un alias pour ls -laOe@ sur mon système

Des faits amusants :

  • Je ne sais pas où se trouve ce fichier (sauf que le fichier est là) - le fichier ne peut pas être trouvé avec sudo find / -name "whatis" dans le système de fichiers
  • Le fichier survit à un redémarrage
  • Je n'ai aucune idée si ce fichier est utilisé par la complétion de l'interpréteur de commandes whatis/apropos/fish|bash|zsh (et résout vos problèmes).

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X