2 votes

Script de menu : comment référencer les utilitaires du chemin utilisateur (le chemin d'accès / l'environnement est manquant)

Résumé

Comment puis-je exécuter des scripts depuis le menu global du Script avec un environnement normal ? Il semble que l'environnement ne soit pas du tout configuré.

Les scripts qui sont exécutés à partir du menu script peuvent trouver et exécuter des commandes du système de base. Cependant, les utilitaires installés par l'utilisateur ne sont pas trouvés sur le chemin. De plus, /usr/bin/env foo ne trouve pas les commandes installées en dehors du système de base.

Contexte

Le menu Script du système apparaît sur le côté droit de la barre de menus. Il est activé via Script Editor.app > Préférences > Afficher le menu Script dans la barre de menus. Il affiche des scripts situés dans ~/Library/Scripts et d'autres emplacements système. Le menu peut exécuter des scripts AppleScript, JXA, bash, python et autres scripts (utilisez un shebang si nécessaire).

description de l'image ici

Enquête Jusqu'à Présent

Les scripts exécutés à partir du menu Script n'héritent pas de l'environnement bash de l'utilisateur. Ils connaissent le shell BASH et le nom de l'utilisateur, mais aucune initialisation ne se produit. J'ai exécuté un petit script pour enregistrer l' env dans un fichier texte

~/Library/Scripts/dump_env.sh (assurez-vous de le rendre exécutable):

#!/bin/bash
env > ~/env.txt
ps -ef >> ~/env.txt

Voici les entrées intéressantes.

USER=mat
LOGNAME=mat
SHELL=/bin/bash
PATH=/usr/bin:/bin:/usr/sbin:/sbin
PWD=/
HOME=/Users/mat
_=/usr/bin/env

C'est très basique. Aucun des chemins personnalisés ne sont inclus. Par exemple, les suivants sont indisponibles :

/usr/local/bin/svn # Client de contrôle de source Subversion
/opt/local/bin/python3 # python3 installé via MacPorts
~/bin

Les deux derniers sont normalement sourcés dans mon .bash_profile. /usr/local/bin/ est configuré par path_helper qui est appelé par /etc/profile (bien que apparemment pas pour le menu Script).

Je suis sous macOS 10.13 High Sierra, mais je suis intéressé de savoir si d'autres obtiennent des résultats différents.

Solution Idéale

  1. Éviter de coder en dur le chemin des exécutables dans le shebang. Par exemple, si j'installe une version/distribution de python différente, je veux l'utiliser dans tous mes scripts. /usr/bin/env python3 permet d'accomplir cela, mais cela semble dépendre du PATH ?
  2. Trouver des utilitaires dans /usr/local/bin
  3. Spécifier le PATH une fois pour l'interface en ligne de commande et le menu Script (et l'interface graphique ?). Si j'installe un nouveau Python, je voudrais qu'il soit utilisé partout.
  4. Spécifier le PATH uniquement pour les processus de niveau utilisateur. Je ne veux pas que les processus système utilisent des binaires à partir de mes entrées de chemin d'extension (surtout les entrées de chemin d'extension avec les permissions utilisateur).
  5. Éviter de casser les installations/programmes tiers qui ont été écrits en supposant ce qui est présent sur mon installation macOS.

Je regarde launchctl, qui peut être utilisé pour configurer l'environnement des applications graphiques. Je ne sais pas si cela fonctionne toujours ou s'il fonctionnera avec le menu Script.

Mise à Jour


J'ai ajouté des déclarations de traçage à tous les fichiers d'environnement bash : /profile, /bashrc, ~/.bash_profile, ~/.bashrc. Ces déclarations exportent des variables d'environnement pour que je puisse voir que le fichier a été sourcé. Aucun de ceux-ci n'est exécuté pour les scripts exécutés à partir du menu Script.

launchctl setenv CLÉ VALEUR définira une variable d'environnement pour tous les processus lancés ultérieurement par les services de lancement (launchd) dans l'espace utilisateur.

Cela fonctionne pour Terminal.app, les applications GUI et les scripts qui sont double-cliqués dans le Finder. Cependant, cela ne fonctionne pas pour le menu Script.

J'ai ajouté ps -ef au script dump_env.sh. Cela me dit que le menu Script n'appelle pas bash avec des arguments qui supprimeraient l'environnement (comme -r ou -p). Le processus parent est UserScriptService.

En cours d'exécution…

otool -tV /System/Library/Frameworks/Foundation.framework/Versions/C/XPCServices/com.apple.foundation.UserScriptService.xpc/Contents/MacOS/com.apple.foundation.UserScriptService.

…révèle un symbole nommé __NSUserScriptTaskServiceStart. Cela ressemble étrangement à NSUserScriptTask dans l'API CoreFoundation. D'après la documentation de l'API :

La classe NSUserScriptTask est capable d'exécuter tous les scripts normalement exécutés par l'un de ses sous-classes…

https://developer.apple.com/documentation/foundation/nsuserscripttask?language=objc

Je soupçonne fortement que c'est ce que le menu Script utilise pour exécuter les scripts. La documentation de l'API ne dit rien sur l'environnement d'exécution du script.

1voto

Tony Williams Points 11219

bash peut démarrer de trois manières différentes et la façon dont il utilise les fichiers rc est différente dans chaque cas.

Pour donner une réponse brève, lorsqu'il est appelé en tant que shell de connexion, il lit .profile ou .bash_profile pour définir des choses comme PATH. Lorsqu'il est appelé en tant que shell interactif mais pas en tant que shell de connexion, par exemple si vous exécutez bash à partir de la ligne de commande, alors il lit ~/.bashrc pour définir ces choses.

S'il est lancé à partir d'un script shell (ou par launchctl), il recherche une variable d'environnement BASH_ENV et exécute le fichier nommé dans la variable.

Vérifiez https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html

Pour répondre à votre question, vous devriez définir toutes les variables dans .bashrc, appeler cela dans votre fichier .bash_profile avec la ligne if [ -f ~/.bashrc ]; then source ~/.bashrc; fi Enfin, dans .bashrc, vous devriez définir la variable BASH_ENV export BASH_ENV='.bashrc'

Cela vous donnerait alors un PATH et ainsi de suite partout.

Lorsque vous passez au shell zsh, les choses sont légèrement différentes, consultez http://zsh.sourceforge.net/Intro/intro_3.html

La plupart des administrateurs et ingénieurs Mac ignorent tout cela et nous codons en dur le chemin de tous nos logiciels dans les scripts. Je n'ai certainement jamais vu de script Apple qui n'avait pas tous les chemins d'outils codés en dur.

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