NOTA: Respuesta aún en construcción...
Una sección más para escribir, detallando los scripts que sincronizarán el estado de ejecución de las aplicaciones. Primero tengo que escribir estos scripts.
Objetivo
En términos generales, idear un medio para que dos Mac guarden y compartan información sobre el entorno de usuario, incluidos los estados/propiedades de las aplicaciones, los documentos cargados y las aplicaciones en ejecución activa. .
Su solicitud inicial era pasar sin problemas de una [máquina] a otra y recrear el estado de las aplicaciones abiertas que tenía en la anterior con un comando. Desde entonces ha relajado un poco sus expectativas y ha aclarado que no se busca "recargar en caliente" las aplicaciones, y que minucias como el tamaño y la posición de las ventanas no son motivo de preocupación.
Metodología conceptual
1. Dos scripts + un fichero de datos compartido
Mi idea inicial era tener una copia de un script (probablemente un AppleScript) en cada máquina que tuviera un manejador encargado de obtener información sobre los entornos de aplicación y almacenarla en un archivo compartido al que ambas máquinas tuvieran acceso (por ejemplo, a través de Dropbox , iCloud , ...). El script tendría un manejador separado que recuperaría el contenido de este archivo compartido, y aplicaría los ajustes al entorno local. Esto requeriría que el usuario ejecute el script una vez al llegar a una máquina para aplicar la configuración; y una vez justo antes de salir de la máquina para actualizar el archivo de datos compartidos con la nueva configuración.
2. .savedState
sincronización
Mi segundo pensamiento se inspiró en la idea de otra persona de sincronizar el archivo ubicado en ~/Library/Preferences/ByHost/com.apple.loginwindow.*
. Aunque hacerlo no sería útil, plantea la cuestión de si sincronizar .savedState
que se encuentran en la carpeta ~/Library/Saved Application State
sería la solución.
Es cierto que no puedo afirmar que sepa cuáles serían todas las ramificaciones de intentar sincronizar estos archivos en dos sistemas diferentes. Eso no quiere decir que vaya a pasar nada malo, pero es territorio desconocido, así que existe la posibilidad de que se produzcan resultados indeseables. Sin embargo, tengo la sensación de que en gran medida sería seguro, y probablemente bastante inocuo, dado que, si algo saliera mal por un mal .savedState
la solución es casi siempre eliminar el archivo .savedState
y permitir que la aplicación en cuestión genere uno nuevo.
Sospecho que se necesitará una combinación de estos dos métodos.
Sincronización
Sincronización de los ~/
carpeta a través de Dropbox
Sincronizar la carpeta de inicio probablemente sólo le proporcionaría un medio para hacer que los documentos estén disponibles en cada máquina, pero posiblemente no le permitiría sincronizar el ~/Library
si no se puede cambiar su ubicación. Además, esta carpeta tiene un tamaño de 26 GB en mi sistema, por lo que implicaría pagar una suscripción por espacio de almacenamiento adicional en la nube.
En última instancia, si la sincronización de la carpeta de inicio se limita a Downloads
, Documents
, Music
y Movies
no es una gran ventaja con respecto a tener el Documents
y Desktop
carpetas sincronizadas a través de iCloud .
Sin embargo, tener los documentos sincronizados es una buena idea, ya que será importante tener acceso a los mismos archivos en ambos ordenadores, y que los cambios en uno se reflejen en el otro. iCloud aunque bastante lento, está bien para este trabajo.
Sincronización de los ~/Library
carpeta
En ~/Library
o al menos subcarpetas específicas de la misma, sería un objetivo crucial si se contempla utilizar .savedState
para asignar estados de aplicación de un sistema a otro. Una solución doméstica de almacenamiento en la nube sería ideal para esta tarea, ya que no cobra ninguna cuota de suscripción; sus datos confidenciales estarían a salvo en su poder y no serían propiedad de Dropbox o Apple y no habría ninguna limitación de velocidad aparte de la impuesta por tu ISP si sincronizas a través de Internet.
Ya utilizo Sincronización Resilio que es gratuito para uso individual y utiliza transferencias peer-to-peer para mantener sincronizadas las carpetas seleccionadas entre cualquier máquina o dispositivo en el que instales la aplicación. Bastaría con seleccionar la carpeta ~/Library
o la carpeta ~/Library/Saved Application State
en tiempo real. Las carpetas pueden permanecer donde están, y si decides pagar por funciones adicionales (pago único), puedes sincronizar selectivamente archivos individuales dentro de una carpeta, y cifrarlos para la seguridad de los datos. Realmente recomiendo esta aplicación, y parece ideal para esta situación específica.
Scripting
Si se sincroniza el .savedState
tiene éxito, lo que podría necesitarse es un script para abrir (o reabrir) las aplicaciones que se estaban ejecutando en la otra máquina. La reapertura hará que la aplicación lea sus archivos actualizados. .savedState
y replicar el estado en que se encontraba en el otro sistema. Creo que esto tendrá un éxito parcial, pero quizás no total.
Recuperar una lista de aplicaciones en ejecución
Esto es más complicado de lo que parece porque hay varias formas de comprobar si una aplicación se está ejecutando, y ninguna prueba es perfecta. Están las aplicaciones en primer plano que son visibles con Windows; están las aplicaciones de la barra de menús, algunas sin Windows, que se ejecutan como procesos en segundo plano; y podría haber aplicaciones ocultas minimizadas en el dock, sin Windows visible.
Después de experimentar con algunos métodos diferentes en AppleScript, esta línea de código parece producir una buena lista exhaustiva de aplicaciones en ejecución, incluidas las aplicaciones de la barra de menús:
tell application "System Events" to set OpenApps to the ¬
name of every application process whose ¬
class of its menu bar contains menu bar and ¬
POSIX path of the application file does not start with "/System" and ¬
POSIX path of the application file does not start with "/Library"
Tarda un par de segundos en devolver un resultado, pero no creo que la velocidad importe demasiado si los scripts se implementan de forma sensata.
Un método Bash para obtener una lista de aplicaciones en ejecución es el siguiente:
IFS=$'\r\n'; basename $( \
egrep -i -e '^/Applications/.*\.app/Contents/MacOS/[^/]+$' \
<<<"$(ps -U 501 -o 'comm')" ) | sort -u
Es rápido (instantáneo), pero echa de menos un par de aplicaciones en la barra de menús y en segundo plano.
Creo que cualquiera de los dos métodos estará bien en última instancia para lo que se necesita, ya que las aplicaciones más importantes para capturar son aquellas con las que se está interactuando en primer plano, y esas son capturadas por la mayoría de los métodos.
Almacenamiento de información en un archivo de configuración compartido
La escritura de los ajustes que deben guardarse puede hacerse en un .plist
que almacena pares clave/valor de datos junto con los tipos de datos. Esto permite guardar y recuperar cualquier valor por su nombre. También son relativamente fáciles de leer y editar mediante programación con AppleScript o la utilidad de línea de comandos plutil
.
Supongamos que el archivo de configuración compartida se guardará en ~/Example/savedState.plist
donde ~/Example/
es algún tipo de carpeta compartida (por ejemplo, una carpeta de almacenamiento en la nube) a la que ambos ordenadores tienen acceso.
Utilizando AppleScript, así es como se puede guardar una lista de las aplicaciones que están abiertas en ese momento:
property plist : "~/Example/SavedState.plist"
tell application "System Events"
if not (the file plist exists) then make new property list file ¬
with properties {name:plist}
set plistf to the property list file named plist
tell plistf to make new property list item with properties ¬
{name:"OpenApps", kind:list, value:OpenApps}
end tell
donde la variable OpenApps
se ha tomado del fragmento de AppleScript anterior. Ingeniosamente, el make new property list
comando sobrescribir cualquier elemento clave/valor existente que ya tenga el nombre "OpenApps"
para que no se duplique.
A continuación, necesitamos una forma de salir de las aplicaciones en un sistema:
to kill(A as list, X as list)
local A, X
if A = {} then return
script jury
property A0 : item 1 of A
property An : rest of A
property OK : A0 is not in X
end script
tell the jury
ignoring application responses
if its OK then quit the application named (its A0)
kill(its An, X)
end ignoring
end tell
end kill
Se trata de un gestor recursivo al que se le pasa una lista de aplicaciones a abandonar (parámetro A
) y una lista de aplicaciones que deben excluirse (parámetro X
). Luego recorre la lista una por una y comprueba que la aplicación no es una de las que están en X
antes de abandonarla y pasar al resto de la lista.
Reapertura de documentos
Mediante el uso de .savedState
se espera que, una vez reiniciada una aplicación en un sistema (por ejemplo, cerrándola y abriéndola de nuevo), vuelva a abrir los documentos que estaban abiertos en el otro.
Sin embargo, puede ser prudente almacenar nuestra propia lista de documentos que podemos detectar (en la medida de nuestras posibilidades) que están abiertos y activos.
[NOTAS PARA QUE LAS INTEGRE EN LA RESPUESTA]
- He notado que algunos
.savedState
se almacenan en ~/Library/Saved Application State
como alias (enlaces simbólicos) en lugar del propio archivo. Estos enlaces suelen ser ~/Library/Containers/%bundle-id%/Data/Library/Saved Application State/%file%
donde %bundle-id%
es, por ejemplo, com.apple.Preview
y su correspondiente %file%
es com.apple.Preview.savedState
.
Esto significa que ~/Library/Containers
probablemente también tendrá que sincronizarse entre las dos máquinas.
.savedState
se borran cada vez que una aplicación sale limpiamente. Por lo tanto, tenga en cuenta que al cerrar las aplicaciones en un sistema se borrarán esos archivos de datos y, a continuación, es posible que se sincronicen estos borrados con la otra máquina.
0 votos
No veo por qué no sería posible si ambas máquinas tuvieran acceso a un sistema de archivos compartido que pudiera leer/escribir datos en el archivo SavedState. ¿Cómo lo harías? Un iCloud o una carpeta Dropbox carpeta. Si tus máquinas son accesibles en una dirección IP fija a través de Internet, puedes incluso enviar Apple Events desde AppleScript entre ellas, pero creo que este no sería el primer método a probar. Yo me inclinaría por un script en cada ordenador y un archivo SavedState compartido que se sincronice entre los dos.
0 votos
Ese es el objetivo. La cuestión es cómo . Alguien me sugirió que sincronizara
~/Library/Preferences/ByHost/com.apple.loginwindow.*
en los dos ordenadores.0 votos
Eso por sí solo es insuficiente, pero la premisa es buena. Lo pensaré y te lo diré. Hay específicos por aplicación
.savedstate
así que lo investigaré.0 votos
Gracias. Yo también he empezado una recompensa para ver si consigo llamar la atención. De acuerdo con sus sugerencias, he estado buscando en
~/Library/Saved Application State/
. Parece que sincronizar ese directorio + un applescript para saber qué aplicaciones abrir ¿podría funcionar?