{"id":2279,"date":"2017-04-27T10:45:15","date_gmt":"2017-04-27T10:45:15","guid":{"rendered":"https:\/\/esferas.org\/msqlu\/?p=2279"},"modified":"2017-04-27T10:45:15","modified_gmt":"2017-04-27T10:45:15","slug":"tal-vez-compartir-fisicamente-un-ordenador","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2017\/04\/27\/tal-vez-compartir-fisicamente-un-ordenador\/","title":{"rendered":"Tal vez compartir f\u00edsicamente un ordenador &#8230;"},"content":{"rendered":"<div class='__iawmlf-post-loop-links' style='display:none;' data-iawmlf-post-links='[{&quot;id&quot;:762,&quot;href&quot;:&quot;https:\\\/\\\/wiki.archlinux.org\\\/index.php\\\/SLiM#Set_default_username&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20250709160240\\\/https:\\\/\\\/wiki.archlinux.org\\\/index.php\\\/Slim&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/wiki.archlinux.org\\\/title\\\/SLiM&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:763,&quot;href&quot;:&quot;http:\\\/\\\/fluxbox.org&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260415152940\\\/https:\\\/\\\/fluxbox.org\\\/&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/fluxbox.org\\\/&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:764,&quot;href&quot;:&quot;http:\\\/\\\/burtonini.com\\\/wordpress\\\/tag\\\/devilspie&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:765,&quot;href&quot;:&quot;http:\\\/\\\/tomas.styblo.name\\\/wmctrl&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:766,&quot;href&quot;:&quot;https:\\\/\\\/manpages.debian.org\\\/jessie\\\/fluxbox\\\/fluxbox-apps.5.en.html&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260415153015\\\/https:\\\/\\\/manpages.debian.org\\\/jessie\\\/fluxbox\\\/fluxbox-apps.5.en.html&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:767,&quot;href&quot;:&quot;https:\\\/\\\/forum.xfce.org\\\/viewtopic.php?pid=13147#p13147&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20260415153022\\\/https:\\\/\\\/forum.xfce.org\\\/viewtopic.php?pid=13147&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:768,&quot;href&quot;:&quot;http:\\\/\\\/search.cpan.org\\\/~gbrown\\\/X11-WMCtrl-0.03\\\/lib\\\/X11\\\/WMCtrl.pm&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20180522070744\\\/http:\\\/\\\/search.cpan.org\\\/~gbrown\\\/X11-WMCtrl-0.03\\\/lib\\\/X11\\\/WMCtrl.pm&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-15 15:27:32&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-15 15:27:32&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;}]'><\/div>\n<p>&#8230; no sea tan malo como suena.<\/p>\n<p><!--more--><\/p>\n<p>Como mencion\u00e9 en esta <a href=\"https:\/\/esferas.org\/msqlu\/2017\/04\/17\/empleando-network-manager-en-un-puesto-solitario\/\">otra entrada,<\/a> en mi trabajo me han encargado que sit\u00fae una m\u00e1quina en la mesa de pedidos para que sea utilizada por tres personas -como m\u00ednimo- y m\u00e1s o menos al mismo tiempo.<\/p>\n<p>El uso compartido es relativo: todos deben poder acceder a una aplicaci\u00f3n web con su usuario correspondiente pero el acceso f\u00edsico a la m\u00e1quina tiene que simplificarse todo lo posible.<\/p>\n<p>As\u00ed que tenemos un sistema Linux que debe:<\/p>\n<ol>\n<li>Arrancar el entorno gr\u00e1fico autom\u00e1ticamente y sin contrase\u00f1a.<\/li>\n<li>Lanzar un navegador web para cada uno de los tres operarios fijos con su correspondiente perfil.<\/li>\n<li>Permitir el cambio de operador sin necesitar contrase\u00f1as.<\/li>\n<\/ol>\n<p>Parece m\u00e1s una cuesti\u00f3n de recursos que de t\u00e9cnica, pero voy a ver de cerca c\u00f3mo podemos ir cumpliendo los requerimientos.<\/p>\n<h3>Arrancar el entorno gr\u00e1fico autom\u00e1ticamente<\/h3>\n<p>En el escritorio <em>corporativo<\/em> se emplea el programa slim para dar acceso al sistema por lo que la primera opci\u00f3n consiste en configurarlo para que acceda autom\u00e1ticamente al sistema.<\/p>\n<p>Seg\u00fan la documentaci\u00f3n que <a href=\"https:\/\/wiki.archlinux.org\/index.php\/SLiM#Set_default_username\">he encontrado<\/a> basta con cambiar la configuraci\u00f3n del programa, situada en <code>\/etc\/slim.conf<\/code> y a\u00f1adir lo siguiente:<\/p>\n<pre class=\"lang:default decode:true \"># default user, leave blank or remove this line\r\n# for avoid pre-loading the username.\r\ndefault_user        almacen\r\n\r\n# Automatically login the default user (without entering\r\n# the password. Set to \"yes\" to enable this feature\r\nauto_login          yes\r\n<\/pre>\n<p>As\u00ed pues ya tendr\u00edamos una cuenta real del sistema (<em>almacen<\/em>) que inicia sesi\u00f3n seg\u00fan arranca el sistema.<\/p>\n<h3>Un navegador web para cada operario<\/h3>\n<p>El escritorio <em>corporativo<\/em> que mencion\u00e9 antes incluye un mont\u00f3n de ejecutables lanzados tras el arranque y est\u00e1 pensando para dar al operador bastante libertad en cuanto a programas que usa, pero no para que el sistema funcione en modo quiosco.<\/p>\n<p>Afortunadamente invert\u00ed mucho tiempo en su momento para hacer que el escritorio fuese muy flexible. Eleg\u00ed <a href=\"http:\/\/fluxbox.org\/\">fluxbox<\/a> ya que permite construir su configuraci\u00f3n con archivos de texto plano y es ligero y muy manejable.<\/p>\n<p>Al final su funcionamiento se reduce a, una vez que lanza ajustes de teclado, un tema y un componente VNC para acceso remoto al escritorio, invocar un simple <em>script<\/em> de usuario para ejecutar lo que se quiera. El servidor X ya est\u00e1 inicializado y s\u00f3lo falta el gestor de ventanas en s\u00ed, que va a continuaci\u00f3n.<\/p>\n<p>Para lograr que cada operario tenga su propia sesi\u00f3n de navegador voy a utilizar los perfiles de Firefox. <a href=\"https:\/\/esferas.org\/msqlu\/wp-content\/uploads\/sites\/12\/2017\/04\/Selecci\u00f3n_128.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-2282\" src=\"https:\/\/esferas.org\/msqlu\/wp-content\/uploads\/sites\/12\/2017\/04\/Selecci\u00f3n_128-300x214.png\" alt=\"\" width=\"300\" height=\"214\" srcset=\"https:\/\/esferas.org\/msqlu\/wp-content\/uploads\/sites\/12\/2017\/04\/Selecci\u00f3n_128-300x214.png 300w, https:\/\/esferas.org\/msqlu\/wp-content\/uploads\/sites\/12\/2017\/04\/Selecci\u00f3n_128.png 522w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Esto es, creo un perfil por cada usuario web y en el arranque los lanzo situ\u00e1ndolos en escritorios virtuales diferentes. Los archivos de la cuenta local <em>almacen<\/em> quedan de la siguiente forma:<\/p>\n<pre class=\"lang:default decode:true\">$HOME\/.mozilla\/\r\n\u2514\u2500\u2500 firefox\r\n    \u251c\u2500\u2500 81k5pnyr.maxi\r\n    \u251c\u2500\u2500 p9vfybia.dani\r\n    \u251c\u2500\u2500 profiles.ini\r\n    \u2514\u2500\u2500 smm9rd24.miguel\r\n<\/pre>\n<p>Y en este punto tengo varias opciones para hacer lo que pretendo:<\/p>\n<ol>\n<li>Emplear el mecanismo <em>apps<\/em> de fluxbox.<\/li>\n<li>Usar el programa <a href=\"http:\/\/burtonini.com\/wordpress\/tag\/devilspie\"><em>devilspie<\/em><\/a>.<\/li>\n<li>Emplear el programa <a href=\"http:\/\/tomas.styblo.name\/wmctrl\/\"><em>wmctrl<\/em><\/a>.<\/li>\n<\/ol>\n<p>El mecanismo <a href=\"https:\/\/manpages.debian.org\/jessie\/fluxbox\/fluxbox-apps.5.en.html\">apps<\/a> de fluxbox no est\u00e1 mal pensando. En el archivo <code>$HOME\/.fluxbox\/apps<\/code> conserva la configuraci\u00f3n de ventanas con un mecanismo de selecci\u00f3n y la posibilidad de designar posici\u00f3n, tama\u00f1o, escritorio y otras cosas m\u00e1s. No es muy c\u00f3modo eso s\u00ed, y en mi experiencia he visto como es f\u00e1cilmente manipulable por el usuario con un par de toques de rat\u00f3n. Tendr\u00eda que conservar una copia para reemplazarla o intervenir directamente en la sesi\u00f3n gr\u00e1fica.<\/p>\n<p>Los programas <em>devilspie<\/em> y <em>wmctrl<\/em> funcionan de manera similar. Se emplean desde un script normal, lanzando primero las ventanas y luego organiz\u00e1ndolas. Una buena explicaci\u00f3n est\u00e1 en <a href=\"https:\/\/forum.xfce.org\/viewtopic.php?pid=13147#p13147\">esta respuesta<\/a> en un foro de xfce.<\/p>\n<p>La diferencia entre los dos estriba en su forma de seleccionar ventanas y su gesti\u00f3n posterior de las mismas, adem\u00e1s de que <em>devilspie<\/em> a\u00f1ade un servicio (<em>daemon<\/em>) y <em>wmctrl<\/em> no.<\/p>\n<p>Por mi parte he escrito un peque\u00f1o script en Perl para realizar justamente esa parte.<\/p>\n<pre class=\"lang:perl decode:true\">#!\/usr\/bin\/perl\r\n\r\nuse Modern::Perl;\r\nuse Getopt::Long;\r\nuse Pod::Usage;\r\nuse POSIX qw(setsid);\r\nuse User::pwent;\r\n \r\nuse X11::WMCtrl;\r\nuse UI::Dialog;\r\n\r\n#   Variables   \r\nmy  $VERSION        =   0.3;\r\nmy  $help           =   0;\r\nmy  $verbose        =   0;\r\nmy  $exit_code      =   0;\r\nmy  $web_browser    =   q(firefox);\r\nmy  $sleep          =   2;\r\n\r\n#   Entrada de par\u00e1metros\r\nGetOptions( 'help:s'    =&gt;  \\$help,\r\n            'verbose'   =&gt;  \\$verbose,\r\n            'quiet'     =&gt;  sub { $verbose = 0; },\r\n            'browser:s' =&gt;  \\$web_browser,\r\n            'sleep:i'   =&gt;  \\$sleep,\r\n    ) or pod2usage ( 1 );\r\npod2usage( 2 ) if $help;\r\n\r\n# Inicializaci\u00f3n \r\nour $ui = UI::Dialog-&gt;new( title =&gt; 'Navegadores', \r\n                order =&gt; [ qw(zenity xdialog) ] );\r\nour $wmctrl = X11::WMCtrl-&gt;new();\r\n\r\nour $desktop = 0;\r\n\r\nforeach my $name (@ARGV) {\r\n    # Obtenemos informaci\u00f3n \r\n    my $ent = getpwnam( $name );\r\n    my $fullname = $name;\r\n\r\n    if (not $ent) {\r\n        $ui-&gt;msgbox(title =&gt; 'error', \r\n            text =&gt; \"El usuario ${name} no existe\" );\r\n        next;\r\n    } \r\n    else {\r\n        ($fullname) = split \/\\s*,\\s*\/, $ent-&gt;gecos;\r\n    }\r\n\r\n    # Lanzamos el navegador con el perfil indicado\r\n    if (my $ret = launch_app( program   =&gt; $web_browser,\r\n                              args      =&gt; [\r\n                                '--new-instance',\r\n                                \"-P $name\",\r\n                                \"--url https:\/\/erp.enexma.net\",\r\n                              ],\r\n                              title     =&gt; $fullname,\r\n                              desktop   =&gt; $desktop ) ne 'OK') {\r\n        _show_error($name,$ret);\r\n        next\r\n    }\r\n    else {\r\n        $desktop++;\r\n    }\r\n} # foreach\r\n\r\n# Fin del programa \r\nexit $exit_code;\r\n\r\nsub _show_error {\r\n    my  $name       =   shift;\r\n    my  $errcode    =   shift;\r\n    my  $msg        =   \"\";\r\n\r\n    if ($errcode eq \"FORK\") {\r\n        $msg = \"No he podido ejecutar el navegador\";\r\n    }\r\n    elsif ($errcode eq 'PID') {\r\n        $msg = \"No he encontrado el identificador de la ventana del navegador\";\r\n    }\r\n\r\n    $ui-&gt;msgbox( title =&gt; 'error', text =&gt; sprintf(\"Error en perfil %s: %s\",\r\n            $name, $msg ));\r\n\r\n    return;\r\n}\r\n\r\nsub launch_app {\r\n    my  %params =   (\r\n        program     =&gt;  undef,\r\n        args        =&gt;  [],\r\n        title       =&gt;  undef,\r\n        desktop     =&gt;  0,\r\n        @_ );\r\n    my  $error      =   \"OK\";\r\n\r\n    my $child_pid = fork();\r\n\r\n    if (not defined $child_pid) {\r\n        $error = \"FORK\";\r\n    }\r\n    elsif ($child_pid == 0) {\r\n        # Somos el proceso hijo\r\n        POSIX::setsid();\r\n        my $cmd = join(\" \",$params{program}, @{$params{args}});\r\n        exec $cmd;\r\n    }\r\n    else {\r\n        # Esperamos unos segundos \r\n        sleep($sleep) if $sleep;\r\n\r\n        # e intentamos localizar el id de la ventana para poder modificarla\r\n        if (my $winpid = search_window_from_pid( $wmctrl-&gt;wmctrl('-lp'),\r\n                $child_pid )) {\r\n            # Situamos la ventana en un escritorio\r\n            $wmctrl-&gt;wmctrl('-i', '-r', \"${winpid}\", '-t', $params{desktop});\r\n            \r\n            # cambiamos el t\u00edtulo \r\n            my $longtitle = sprintf(\"'%s'\",$params{title});\r\n            $wmctrl-&gt;wmctrl('-i', '-r', \"${winpid}\", '-N', $longtitle );\r\n\r\n            # y la ponemos a pantalla completa\r\n            $wmctrl-&gt;wmctrl('-i', '-r', \"${winpid}\", '-b', 'toggle,fullscreen');\r\n        }\r\n        else {\r\n            $error = \"PID\";\r\n        }\r\n    }\r\n\r\n    return $error;\r\n}\r\n\r\nsub search_window_from_pid {\r\n    my  $data   =   shift;\r\n    my  $pid    =   shift;\r\n\r\n    foreach my $line (split(\/\\n\/,$data)) {\r\n        my ($id,$workspace,$p_id) = split(\/ +\/,$line,4);\r\n\r\n        if ($p_id == $pid) {\r\n            return $id;\r\n        }\r\n    }\r\n\r\n    return undef;\r\n}\r\n\r\n<\/pre>\n<p>Empleo un m\u00f3dulo Perl llamado <a href=\"http:\/\/search.cpan.org\/~gbrown\/X11-WMCtrl-0.03\/lib\/X11\/WMCtrl.pm\">X11::WMCtrl<\/a> bastante decepcionante y algo de UI::Dialog para que los avisos de error sean m\u00e1s visuales.<\/p>\n<p>Por si hay dudas lo que el programa hace es lo siguiente:<\/p>\n<ol>\n<li>Por cada una de las cuentas de usuario que se le proporcionan como par\u00e1metros:\n<ol>\n<li>Busca su nombre completo.<\/li>\n<li>Crea un proceso hijo (fork):\n<ol>\n<li>Independiza la sesi\u00f3n<\/li>\n<li>Lanza el navegador<\/li>\n<\/ol>\n<\/li>\n<li>En el proceso padre:\n<ol>\n<li>Espera unos segundos a que aparezca la ventana.<\/li>\n<li>Busca el identificador de la ventana seg\u00fan el ID del proceso.<\/li>\n<li>Modifica la ventana:\n<ol>\n<li>La sit\u00faa en un escritorio concreto.<\/li>\n<li>Cambia el t\u00edtulo por el nombre completo del usuario.<\/li>\n<li>Redimensiona a pantalla completa.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>Y funciona. M\u00e1s o menos, porque existe cierta dependencia del tiempo en el que tarda en aparecer la ventana para poder buscar su PID en la lista y eso puede hacer que la abra y aparezca un mensaje de error al mismo tiempo.<\/p>\n<p>Y como tiempo no tengo no puedo hacerlo m\u00e1s s\u00f3lido. Tendr\u00e1 que servir as\u00ed.<\/p>\n<h3>Queda pendiente<\/h3>\n<p>Ver c\u00f3mo de c\u00f3modo es su uso. Aunque no pueden emplearlo al mismo tiempo en el fondo est\u00e1n utilizando un mismo usuario de sistema (la cuenta <em>almacen<\/em>) as\u00ed que espero dificultades al menos en:<\/p>\n<ol>\n<li>Impresi\u00f3n de trabajos.<\/li>\n<li>Guarda de documentos descargados.<\/li>\n<li>Cierre de sesi\u00f3n y apagado.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; no sea tan malo como suena.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[2],"tags":[18,195,701,52,17,702,703],"class_list":["post-2279","post","type-post","status-publish","format-standard","hentry","category-software","tag-administracion-de-sistemas","tag-firefox","tag-fluxbox","tag-mi-lugar-de-trabajo","tag-perl","tag-slim","tag-wmctrl"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/2279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=2279"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/2279\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=2279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=2279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=2279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}