Me gustaría saber si hay un comando que devuelve el ejecutable dentro del paquete de aplicaciones
No hay tal comando, pero he escrito un script de shell que hace exactamente eso para cualquier paquete de aplicaciones en el sistema de archivos de su disco de inicio .
Utiliza varias herramientas de línea de comandos incluidas en macOS y aprovecha la documentación de Apple en Launch Services , Application Bundles y Core Foundation Keys . El script hace lo siguiente:
- Busca
/Applications
para el paquete de aplicaciones.
- Si no se puede encontrar en
/Applications
, consulta la base de datos de Servicios de lanzamiento, solo considerando paquetes de aplicaciones en el disco de inicio.
- Si se encontró un paquete de aplicaciones, inspecciona el
Info.plist
del paquete y busca una clave llamada CFBundleExecutable
que almacene el archivo ejecutable (consulte más abajo en la sección de información de fondo). De lo contrario, imprima un mensaje de error y una salida.
- Imprime la ruta del ejecutable a la salida estándar.
El script entiende tanto el nombre de una aplicación con o sin su extensión, verifica los argumentos, muestra un mensaje de uso y una breve descripción si se ejecuta sin argumentos y devuelve un estado de salida con un mensaje de error si es necesario.
Como la secuencia de comandos busca /Applications
y puede hacer una consulta lenta a los Servicios de inicio, no es muy rápida (de ~ 1 seg a varios segundos), pero fue 100% precisa en mis pruebas .
Este es el script, con explicaciones sobre lo que se hace en cada paso:
#!/bin/bash
# https://apple.stackexchange.com/a/334635
# Variables
app_name="";
app_path_and_name="";
path_to_lsregister="/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/";
# If run without arguments, issue a usage summary and exit
if [[ "$1" == "" ]]; then
echo "$(basename $0): returns name of bundle applications’s executable file";
echo "usage: $(basename $0) [application name]";
exit 0;
fi;
# If argument doesn't end with '.app', append it
if [[ "$1" =~ \.app$ ]]; then
app_name="$1"
else
app_name="$1.app";
fi;
# Look for the path of the application bundle
# Search /Applicatinos first
app_path_and_name="$(find /Applications -type d -name "$app_name" -maxdepth 5 | grep -m 1 "$app_name")";
# If not found, search the the LaunchServices database (this is the time-consuming task)
test "$app_path_and_name" || app_path_and_name="$($path_to_lsregister/lsregister -dump | grep -v /Volumes | egrep --max-count 1 "/$app_name$" | sed 's:.* \(/.*\)::')"
# Check if Info.plist exists and is readable
if [[ -r "$app_path_and_name/Contents/Info.plist" ]]; then
# Extract the CFBundleExecutable key that contains the name of the executable and print it to standard output
echo "$app_path_and_name/MacOS/$(defaults read "$app_path_and_name/Contents/Info.plist" CFBundleExecutable)";
exit 0;
else
echo "Application '$1' not found";
exit 1
fi
Puede guardar el archivo (por ejemplo, como pbex
para "imprimir paquete ejecutable") y hacerlo ejecutable de la siguiente manera:
chmod a+x pbex
Si prefieres una función, usa esto en su lugar:
function pbex ()
{
# https://apple.stackexchange.com/a/334635
# Variables
local app_name="";
local app_path_and_name="";
local path_to_lsregister="/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/";
# If run without arguments, issue a usage summary and exit
if [[ "$1" == "" ]]; then
echo "$FUNCNAME: returns name of bundle applications’s executable file";
echo "usage: $FUNCNAME [application name]";
return 0;
fi;
# If argument doesn't end with '.app', append it
if [[ "$1" =~ \.app$ ]]; then
app_name="$1"
else
app_name="$1.app";
fi;
# Look for the path of the application bundle
# Search /Applicatinos first
app_path_and_name="$(find /Applications -type d -name "$app_name" -maxdepth 5 | grep -m 1 "$app_name")";
# If not found, search the LaunchServices database (this is the time-consuming step)
test "$app_path_and_name" || app_path_and_name="$($path_to_lsregister/lsregister -dump | grep -v /Volumes | egrep --max-count 1 "/$app_name$" | sed 's:.* \(/.*\)::')"
# Check if Info.plist exists and is readable
if [[ -r "$app_path_and_name/Contents/Info.plist" ]]; then
# Extract the CFBundleExecutable key that contains the name of the executable and print it to standard output
echo "$app_path_and_name/MacOS/$(defaults read "$app_path_and_name/Contents/Info.plist" CFBundleExecutable)";
return 0;
else
echo "Application '$1' not found";
return 1
fi
}
Solo agrégalo a .bashrc
, fuente:
. .bashrc
para usar la función.
Si necesita ejecutarlo como "una sola línea" (bastante larga), use (reemplace <app name>
con el nombre de la aplicación sin la extensión .app):
bash -c "app_name=\"<app name>\.app"; app_path_and_name=\"\"; if [[ \"\$app_name\" == \"\" ]]; then exit 2; fi; app_path_and_name=\"\$(find /Applications -type d -name \"\$app_name\" -maxdepth 5 | grep -m 1 \"\$app_name\")\"; test \"\$app_path_and_name\" || app_path_and_name=\"\$(/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep -v /Volumes | egrep --max-count 1 \"/\$app_name\$\" | sed \"s:.* \(/.*\)::\")\"; if [[ -r \"\$app_path_and_name/Contents/Info.plist\" ]]; then echo \"\$app_path_and_name/MacOS/\$(defaults read \"\$app_path_and_name/Contents/Info.plist\" CFBundleExecutable)\"; exit 0; else echo \"Application \"\$app_name\" not found\"; exit 1; fi"
(Usted escribe en un comentario que el "comando debe iniciarse desde dentro de un QProcess"). Podrías hacer lo siguiente:
process.start("bash", QStringList() << "-c" << "app_name=\"<app name>\.app"; ...");
Consulte enlace para obtener más información.)
Ejemplos:
$ pbex
pbex: returns name of bundle applications’s executable file
usage: pbex [application name]
$ pbex "Microsoft Edge"
Application 'Microsoft Edge' not found
$ pbex Finder
/System/Library/CoreServices/Finder.app/MacOS/Finder
$ pbex "Quick Look Simulator.app"
/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/QuickLookUI.framework/Versions/A/Resources/Quick Look Simulator.app/MacOS/Quick Look Simulator
$ pbex "BalTax 2016"
/Applications/BalTax 2016/BalTax 2016.app/MacOS/JavaApplicationStub
$ pbex ColorSync\ Utility
/Applications/Utilities/ColorSync Utility.app/MacOS/ColorSync Utility
INFORMACIÓN DE ANTECEDENTES
La estructura de un paquete de aplicaciones del paquete macOS es bien conocida y está documentada por Apple.
Según la estructura de un paquete de aplicaciones macOS , la estructura básica de una aplicación para Mac es:
MyApp.app/
Contents/
Info.plist
MacOS/
Resources/
donde la carpeta MacOS
" contiene el código ejecutable independiente de la aplicación. Normalmente, este directorio contiene solo un archivo binario con el punto de entrada principal de la aplicación y el código vinculado estáticamente Sin embargo, también puede poner otros ejecutables independientes (como herramientas de línea de comandos) en este directorio ".
El archivo Info.plist
es necesario para que el Finder reconozca un paquete de aplicaciones como tal. Esta lista de propiedades de información contiene archivos de lista de propiedades XML que identifican la configuración de su paquete. La clave que nos interesa es CFBundleExecutable
, que almacena " el nombre del archivo ejecutable principal . Este es el código que se ejecuta cuando el usuario inicia su cuenta. aplicación. "