#!/bin/bash ################################################################################ # uso: linuxcnc [opciones] [] # #opciones: # -v = detallado - imprime informacion durante su tarea # -d = eco en terminal de los comandos para depuracion # #Esta version llama a pickconfig.tcl para escojer un fichero ini de entre los de ejemplo, si no #se ha especificado ninguno en la linea de comandos. # ################################################################################ # Author: # License: GPL Version 2 # System: Linux # # Copyright (c) 2004-2009 All rights reserved. # Traduccion al castellano Copyright (c) 2019 All rights reserved. # set añadido para aumentar la info en depuracion. # El valor de $PS4 se expande y el valor resultante se imprime antes del comando y sus argumentos expandidos. # Para ello, ejecutar antes en un terminal: # export PS4='# ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]}() - [${SHLVL},${BASH_SUBSHELL},$?] ' # y descomentar la siguiente linea para expansion de argumentos en depuracion: #set -o xtrace ################################################################################ ################################################################################ # 0.- Valores que se obtuvieron mediante ./configure o en la instalacion de la aplicacion. # Puede haber dos versiones de este mismo scipt: # La montada con el paquete binario o el DVD # La version RIP, o run-in-place, que se obtiene de la compilacion de fuentes en la propia maquina. # Los valores de algunos path's seran diferentes. ################################################################################ prefix=@prefix@ exec_prefix=@exec_prefix@ LSMOD=@LSMOD@ PIDOF="@PIDOF@ -x" PS=@PS@ AWK=@AWK@ GREP=@GREP@ IPCS=@IPCS@ KILL=@KILL@ ################################################################################ # 0.1 Otros directorios o path para otros ficheros. ################################################################################ # Directorio base para una instalacion por paquetes. LINUXCNC_HOME=@EMC2_HOME@; export LINUXCNC_HOME # binarios LINUXCNC_BIN_DIR=@EMC2_BIN_DIR@ # tcl/tk LINUXCNC_TCL_DIR=@EMC2_TCL_DIR@ # documentacion LINUXCNC_HELP_DIR=@EMC2_HELP_DIR@ # librería tiempo real LINUXCNC_RTLIB_DIR=@EMC2_RTLIB_DIR@ # Path's a ficheros de configuraciones LINUXCNC_CONFIG_PATH="@LINUXCNC_CONFIG_PATH@" # ejemplos de ficheros de codigo numerico LINUXCNC_NCFILES_DIR=@EMC2_NCFILES_DIR@ LINUXCNC_LANG_DIR=@EMC2_LANG_DIR@ # script con funciones para realtime REALTIME=@REALTIME@ # archivos de varias imagenes graficas LINUXCNC_IMAGEDIR=@EMC2_IMAGE_DIR@ # biblioteca y scrips tcl LINUXCNC_TCL_LIB_DIR=@EMC2_TCL_LIB_DIR@ # halfiles (* .hal y * .tcl) HALLIB_DIR=@HALLIB_DIR@; export HALLIB_DIR # añadir path hallib. HALLIB_PATH=.:$HALLIB_DIR; export HALLIB_PATH #Colocar camino a binarios LINUXCNC_BIN_DIR en la variable de entorno PATH PATH=$LINUXCNC_BIN_DIR:$PATH # Para instalacion no RIP, (existira directorio $LINUXCNC_HOME/scripts) colocar directorio de scripts en path [ -d $LINUXCNC_HOME/scripts ] && PATH=$LINUXCNC_HOME/scripts:$PATH ################################################################################ # 0.2 DEFINICION DE OTROS PARAMETROS: # LD_LIBRARY_PATH # PYTHONPATH # XFILESEARCHPATH # MODULE_EXT # archivos temporales linuxcnc.debug.XXXXXX y linuxcnc.print.XXXXXX # funciones program_available () y usage () ################################################################################ # Formar la variable LD_LIBRARY_PATH (camino a librerias). Exportarla if test "xyes" = "x@RUN_IN_PLACE@"; then # si la longitud de la cadena contenida en LD_LIBRARY_PATH es cero (no se ha definido)... if [ -z "$LD_LIBRARY_PATH" ]; then # ... definirla LD_LIBRARY_PATH=$LINUXCNC_HOME/lib else LD_LIBRARY_PATH=$LINUXCNC_HOME/lib:"$LD_LIBRARY_PATH" fi export LD_LIBRARY_PATH fi # Formar la variable PYTHONPATH (camino a python). Exportarla if [ -z "$PYTHONPATH" ]; then PYTHONPATH=$LINUXCNC_HOME/lib/python else PYTHONPATH=$LINUXCNC_HOME/lib/python:"$PYTHONPATH" fi export PYTHONPATH # Esta variable parece no ser necesaria. MachineKit, por ejemplo, anula esta linea con un comentario. PRELOAD_WORKAROUND=@PRELOAD_WORKAROUND@ # para el sistema X11 (sistema grafico), especificacion de los path de busqueda de recursos # El significado de los parametros estan definidos en XtResolvePathname de la libreria X # https://www.x.org/archive/current/doc/man/man3/XtResolvePathname.3.xhtml XFILESEARCHPATH=%D:@EMC2_HOME@/%T/%N%C:@EMC2_HOME@/%T/%N export XFILESEARCHPATH #extension de los modulos para cargar en el kernel con insmod (man insmod) MODULE_EXT=@MODEXT@ # directorios para creacion de ficheros de depuracion e impresion temporales (man mktemp) # XXXXXX es una plantilla que mktemp construye automaticamente para cada temporal. DEBUG_FILE=$(mktemp /tmp/linuxcnc.debug.XXXXXX) PRINT_FILE=$(mktemp /tmp/linuxcnc.print.XXXXXX) #FUNCION # validación de disponibilidad de programas # Se usará para verificar algunas de las entradas del .ini que cargan otros programas program_available () { type -path "$1" > /dev/null 2>&1 } # FUNCION # mostrar la ayuda usage () { P=${0##*/} cat <$DEBUG_FILE fi set -x;; v) # Activar modo “verbose” (mostrar informacion) if tty -s; then PRINT_FILE=/dev/fd/1 echo "Modo detallado activo" >$PRINT_FILE fi;; r) RUNTESTS=yes ;; l) USE_LAST_INIFILE=1;; k) DASHK=-k;; h) usage exit 0;; *) usage exit 1 esac done shift $(($OPTIND-1)) ################################################################################ # 1.2. comprobacion de que el sistema operativo tiene la extension de tiempo real ################################################################################ case "@KERNEL_VERS@" in "") ;; *) if [ `uname -r` != "@KERNEL_VERS@" ]; then if tty -s; then echo "LinuxCNC requiere el nucleo real-time @KERNEL_VERS@ ." echo "Antes de correr LinuxCNC, reinicie y elija el nucleo en el menu de arranque." else @WISH@ <> $DEBUG_FILE exec >> $PRINT_FILE fi fi ################################################################################ # 1.4. Definicion funcion tratamiento errores ################################################################################ function ErrorCheck () { result=$? if [ ! -z "$DISPLAY" ]; then echo "catch {send -async popimage destroy .}; destroy ." | @WISH@ fi if [ $result -ne 0 ]; then if tty -s || [ -z "$DISPLAY" ] ; then if [ -f $DEBUG_FILE ]; then cp $DEBUG_FILE $HOME/linuxcnc_debug.txt else echo "(La informacion de depuracion se ha conducido a stderr)" \ > $HOME/linuxcnc_debug.txt fi if [ -f $PRINT_FILE ]; then cp $PRINT_FILE $HOME/linuxcnc_print.txt else echo "(La informacion imprimible se ha conducido a stdout)" \ > $HOME/linuxcnc_print.txt fi echo "\ LinuxCNC terminado con error. Mas informacion en el log: $HOME/linuxcnc_debug.txt y $HOME/linuxcnc_print.txt asi como en la salida del comando shell 'dmesg' y en el terminal" else @WISH@ $LINUXCNC_TCL_DIR/show_errors.tcl $DEBUG_FILE $PRINT_FILE fi fi rm -f $DEBUG_FILE $PRINT_FILE 2>/dev/null exit $result } # EXIT si error trap ErrorCheck EXIT ################################################################################ # 1.5. INIFILE; encontrar el fichero .ini a usar # Se decide si hay un ini en la linea de comandos o si se elegira del selector # Preparacion de algunas variables importantes ################################################################################ if [ ! -z "$1" ]; then case "$1" in -) USE_LAST_INIFILE=1;; /*) INIFILE="$1" ;; *) INIFILE="`pwd`/$1";; esac shift fi EXTRA_ARGS="$@" ################################################################################ # 1.6 No run-in-place ################################################################################ RUN_IN_PLACE=@RUN_IN_PLACE@ echo RUN_IN_PLACE=$RUN_IN_PLACE >>$PRINT_FILE LINUXCNCVERSION="@EMC2VERSION@"; export LINUXCNCVERSION # comun desde aqui... ################################################################################ # 1.7 preparar: # HAL desde linea de comandos, halcmd (con o sin -k) # selector de configuracion pickconfig # shell de ventanas wish para pickconfig ################################################################################ INIVAR=inivar HALCMD="halcmd $DASHK" PICKCONFIG="@WISH@ $LINUXCNC_TCL_DIR/bin/pickconfig.tcl" LINUXCNC_EMCSH=@WISH@ #ecos a archivo temporal imprimible (/tmp/linuxcnc.print.xxxxxx) ################################################################################ echo LINUXCNC_DIR=$LINUXCNC_DIR >>$PRINT_FILE echo LINUXCNC_BIN_DIR=$LINUXCNC_BIN_DIR >>$PRINT_FILE echo LINUXCNC_TCL_DIR=$LINUXCNC_TCL_DIR >>$PRINT_FILE echo LINUXCNC_SCRIPT_DIR=$LINUXCNC_SCRIPT_DIR >>$PRINT_FILE echo LINUXCNC_RTLIB_DIR=$LINUXCNC_RTLIB_DIR >>$PRINT_FILE echo LINUXCNC_CONFIG_DIR=$LINUXCNC_CONFIG_DIR >>$PRINT_FILE echo LINUXCNC_LANG_DIR=$LINUXCNC_LANG_DIR >>$PRINT_FILE echo INIVAR=$INIVAR >>$PRINT_FILE echo HALCMD=$HALCMD >>$PRINT_FILE echo LINUXCNC_EMCSH=$LINUXCNC_EMCSH >>$PRINT_FILE #exportar algunos directorios comunes, disponibles para varias GUI's ################################################################################ export LINUXCNC_TCL_DIR export LINUXCNC_EMCSH export LINUXCNC_HELP_DIR export LINUXCNC_LANG_DIR export REALTIME export HALCMD export LINUXCNC_NCFILES_DIR [ -z $RUNTESTS ] && echo "LINUXCNC - $LINUXCNCVERSION" # Hay fichero ini en linea de comandos? ################################################################################ if [ ! -z "$USE_LAST_INIFILE" ]; then INIFILE=$($INIVAR -ini ~/.linuxcncrc -var LAST_CONFIG -sec PICKCONFIG 2>>$DEBUG_FILE) echo "Usando la ultima configuracion: $INIFILE" >> $PRINT_FILE fi if [ ! -n "$INIFILE" ] ; then # nothing specified, get from the user # it returns either a path, or nothing at all INIFILE=$($PICKCONFIG) # Si el nombre es xxxx.demo, entonces ejecutar xxxx.demo en segundo plano y salir if [ "${INIFILE%%.demo}".demo = "${INIFILE}" ] ; then "${INIFILE}" & exit 0 fi fi if [ ! -n "$INIFILE" ] ; then # still nothing specified, exit exit 0 fi ################################################################################ # 1.8. Funciones: # handle_includes () Tratamiento y expansion de posibles INCLUDEs en el .ini. # split_app_items () Aux para aplicaciones a ejecutar señaladas en la seccion [APPLICATIONS] del .ini # run_applications () Aplicaciones a ejecutar señaladas en la seccion [APPLICATIONS] del .ini ################################################################################ function handle_includes () { hdr="# handle_includes():" inifile="$1" cd "$(dirname $inifile)" ;# solo para el subproceso function() $GREP "^#INCLUDE" "$inifile" >/dev/null status=$? if [ $status -ne 0 ] ; then echo "$inifile" ;# usar la entrada return 0 ;# ok fi outfile="$(dirname $inifile)/$(basename $inifile).expanded" >|"$outfile" echo "#*** $outfile" >>"$outfile" echo "#*** Creado: $(date)" >>"$outfile" echo "#*** Fichero autogenerado con #INCLUDEs expandidos" >>"$outfile" echo "" >>"$outfile" line=0 while read a b ; do line=$((line + 1)) if [ "$a" = "#INCLUDE" ] ; then if [ "X$b" = "X" ] ; then msg="$hdr <$line> Encontrado #INCLUDE sin nombre de fichero" >>"$outfile" echo "$msg" >&2 echo "$msg" >>"$outfile" else # expandir filename breal=$(eval echo "$b") # -r: leible if [ -r "$breal" ] ; then echo "" >>"$outfile" echo "#*** Comienza fichero #INCLUDE: $breal" >>"$outfile" cat "$breal" >>"$outfile" echo "#*** Termina fichero #INCLUDE: $breal" >>"$outfile" else msg="$hdr <$line> NO SE PUEDE LEER $breal" echo "$msg" >&2 echo "$msg" >>"$outfile" fi fi else echo "$a $b" >> "$outfile" fi done <"$inifile" echo "$outfile" ;# usar el fichero expandido return 0 ;# ok } ################################################################################ function split_app_items () { app_name=$1 shift app_args=$* } ################################################################################ function run_applications () { NUM=1 APPFILE=`$INIVAR -tildeexpand -ini "$INIFILE" -var APP -sec APPLICATIONS -num $NUM 2> /dev/null` if [ -z "$APPFILE" ] ; then return ; fi DEFAULT_APPLICATION_DELAY=0 GetFromIni DELAY APPLICATIONS DELAY=${retval:-$DEFAULT_APPLICATION_DELAY} while [ -n "$APPFILE" ] ; do split_app_items $APPFILE # --> app_name app_args # probar especificaciones explicitas antes de intentar PATH case "$app_name" in /*) # nombre de camino absoluto exe_name=$app_name;; \./*) # nombre relativo al directorio inifile exe_name="$(pwd)/$app_name";; *) # intentar locales, luego PATH exe_name=$(pwd)/$app_name if [ ! -x $exe_name ] ; then exe_name=$(which $app_name) fi esac if [ ! -f "$exe_name" ] ; then echo "APP: No se encuentra ejecutable para: <$app_name>" else if [ ! -x "$exe_name" ] ; then echo "APP: Fichero no ejecutable: <$exe_name>" else echo "APP: $app_name encontrada: <$exe_name>" (sleep $DELAY; eval $exe_name $app_args) & fi fi NUM=$(($NUM+1)) APPFILE=`$INIVAR -tildeexpand -ini "$INIFILE" -var APP -sec APPLICATIONS -num $NUM 2> /dev/null` done } ################################################################################# INIFILE="$(handle_includes "$INIFILE")" # eliminar directorio; quedarse con el nombre INI_NAME="${INIFILE##*/}" # eliminar nombre; quedarse con el directorio INI_DIR="${INIFILE%/*}" CONFIG_DIR="${INIFILE%/*}" export CONFIG_DIR export PATH=$CONFIG_DIR/bin:$PATH [ -z $RUNTESTS ] && echo "El directorio de configuracion de la maquina es '$INI_DIR'" echo "El fichero de configuracion de la maquina es '$INI_NAME'" # Asegurar que existe el .ini (el script tcl lo hace, por lo que se podria eliminar este tests. Aun asi, aquí no hace daño) if [ ! -f "$INIFILE" ] ; then echo "No se encuentra fichero ini '$INIFILE'" trap '' EXIT exit -1 fi echo INIFILE="$INIFILE" >>$PRINT_FILE ################################################################################ # 2. Extraer informacion del ini que se necesitara mas tarde # funciones: #GetFromIni Devuelve en retval el valor asociado a un parametro de una seccion # del fichero ini # Uso: GetFromIni VAR SEC (parametro a leer y seccion donde encontrarlo) #GetFromIniQuiet Igual que GetFromIni, pero sin info para depuracion #GetFromIniEx Version multientrada de GetFromIni, con valor por defecto # Uso: GetFromIniEx VAR1 SEC1 [VAR2 SEC2...VARn SECn] [default] # Estas funciones usan $1 y $2 para el nombre de variable y nombre de seccion respectivamente ################################################################################ # variable para contener el retorno de las funciones retval= # funciones de extraccion function GetFromIniQuiet { #$1 var name $2 - section name name=$1 retval=`$INIVAR -ini "$INIFILE" -var $1 -sec $2 2> /dev/null` if [ ! -n "$1" ] ; then exit -1 fi echo "$name=$retval" >>$PRINT_FILE } function GetFromIni { #$1 var name $2 - section name name=$1 retval=`$INIVAR -ini "$INIFILE" -var $1 -sec $2 2>>$DEBUG_FILE` if [ ! -n "$1" ] ; then echo "No se encuentra variable $1 en seccion [$2] del fichero $INIFILE." exit -1 fi echo "$name=$retval" >>$PRINT_FILE } # Uso: # GetFromIniEx VAR1 SEC1 [VAR2 SEC2...VARn SECn] [default] function GetFromIniEx { original_var="[$2]$1" while [ $# -ge 2 ]; do if retval=`$INIVAR -ini "$INIFILE" -var "$1" -sec "$2" 2>/dev/null`; then return; fi shift 2 done if [ $# -eq 0 ]; then echo "No se encuentra $original_var en $INIFILE." exit -1 fi retval="$1" } ################################################################################ # 2.1. Comienza la extraccion de: # fichero de parametros para el interprete RS274NGC (xxxx.var) # modulo motion (por defecto, motmod) # modulo io (por defecto, io) # coordinador de tareas # Servidor NML (codificado explicitamente, linuxcncsvr) # halui # display (GUI a usar) # archivo de configuracion NML (por defecto, /usr/share/linuxcnc/linuxcnc.nml) ################################################################################ # 2.1.1. Extraccion nombre fichero de parametros GetFromIni PARAMETER_FILE RS274NGC RS274NGC_PARAMFILE=$retval # 2.1.2. Extraccion del modulo controlador de movimiento (motmod por defecto) GetFromIniEx MOT MOT EMCMOT EMCMOT motmod EMCMOT=$retval$MODULE_EXT # añadir extension .ko al modulo # 2.1.3. Extraccion del modulo controlador de entrada/salida (io por defecto) GetFromIniEx IO IO EMCIO EMCIO io EMCIO=$retval # 2.1.4. Extraccion del modulo controlador de tareas. Si es emctask, usar linuxcnctask GetFromIni TASK TASK EMCTASK=$retval if [ "$EMCTASK" = emctask ]; then EMCTASK=linuxcnctask; fi # 2.1.5. Nombre del servidor. Codificado explicitamente. cambiar si es necesario. # linuxcncsvr mantiene/crea todos los canales NML, por tanto es necesario arrancarlo como primer proceso. EMCSERVER=linuxcncsvr # 2.1.6. Extraccion del modulo interfaz usuario HAL GetFromIniQuiet HALUI HAL HALUI=$retval # 2.1.7. Extraccion del interfaz de usuario GetFromIni DISPLAY DISPLAY EMCDISPLAY=`(set -- $retval ; echo $1 )` EMCDISPLAYARGS=`(set -- $retval ; shift ; echo $* )` case $EMCDISPLAY in tkemc) EMCDISPLAY=tklinuxcnc ;; xemc) EMCDISPLAY=xlinuxcnc ;; esac # 2.1.8. Extraccion de configuracion de canales NML (/usr/share/linuxcnc/linuxcnc.nml por defecto) GetFromIniEx NML_FILE LINUXCNC NML_FILE EMC @DEFAULT_NMLFILE@ NMLFILE=$retval export NMLFILE ################################################################################ # 3.Hecha recopilación de información, definir algunas funciones # La ejecución se reanuda después de las definiciones de funciones ... ################################################################################ KILL_TASK= KILL_TIMEOUT=20 ################################################################################ # 3.1. Elimina una lista de tareas con tiempo de espera # Si no funciona, se utiliza kill -9 (matar todos los procesos que se puedan) ################################################################################ function KillTaskWithTimeout() { if [ ! -n "$KILL_PIDS" ] ; then KILL_PIDS=`$PIDOF $KILL_TASK` fi if [ ! -n "$KILL_PIDS" ] ; then echo "No se encuentra pid(s) para tarea $KILL_TASK" return -1 fi local NPROCS for KILL_PID in $KILL_PIDS ; do if $PS -o comm= $KILL_PID | $GREP -q ''; then echo "Skipping defunct task $KILL_TASK, PID=$KILL_PID" >>$PRINT_FILE continue fi # primero, matar “educadamente” con la señal TERM $KILL $KILL_PID WAIT=$KILL_TIMEOUT # esperar para ver si ha muerto while [ $WAIT -gt 1 ] ; do # ver si sigue viva NPROCS=$($PS -o comm= $KILL_PID | $GREP -v '' | wc -l) if [ $NPROCS -gt 0 ]; then WAIT=$(($WAIT-1)) sleep .1 else WAIT=0 fi done if [ $WAIT -gt 0 ] ; then # la educacion no ha funcionado, pongamonos serios echo "Fin de tiempo, intentando forzar con kill -9" >>$PRINT_FILE $KILL -9 $KILL_PID WAIT=$KILL_TIMEOUT #esperar a su muerte while [ $WAIT -gt 1 ] ; do #ver si sigue viva NPROCS=$($PS -o comm= $KILL_PID | $GREP -v '' | wc -l) if [ $NPROCS -gt 0 ]; then WAIT=$(($WAIT-1)) sleep .1 else WAIT=0 fi done fi if [ $WAIT -gt 0 ] ; then echo "No se puede matar la tarea $KILL_TASK, PID=$KILL_PID" fi done KILL_PIDS= KILL_TASK= } ################################################################################ # 3.2. define la funcion de limpieza # # Esta funcion ni sabe ni le importa lo que hay cargado- simplemente mata cualquier proceso de su lista ################################################################################ function Cleanup() { echo "Apagando y limpiando LinuxCNC..." # Matar primero los displays – esto causara un apagado ordenado del resto de linuxcnc # Y ahora, la lista for KILL_TASK in xlinuxcnc ylinuxcnc linuxcncpanel keystick iosh linuxcncsh linuxcncrsh linuxcnctop mdi debuglevel; do if $PIDOF $KILL_TASK >>$DEBUG_FILE ; then KillTaskWithTimeout fi done if program_available axis-remote ; then if [ ! -z "$DISPLAY" ]; then axis-remote --ping && axis-remote --quit fi fi if [ "$1" = "other" ]; then echo -n "Esperando que otra sesion termine su salida..." WAIT=$KILL_TIMEOUT while [ $WAIT -gt 1 ]; do if ! [ -f $LOCKFILE ]; then echo " Ok" return 0 fi WAIT=$(($WAIT-1)) sleep .1 done echo "Fichero de bloqueo aun no eliminado" fi SHUTDOWN=`$INIVAR -ini "$INIFILE" -var SHUTDOWN -sec HAL 2> /dev/null` if [ -n "$SHUTDOWN" ]; then echo "Corriendo el script de apagado HAL" $HALCMD -f $SHUTDOWN fi # se matan ahora los otros componentes de espacio de usuario ( linuxcncsvr, milltask ) for KILL_TASK in linuxcncsvr milltask; do if $PIDOF $KILL_TASK >>$DEBUG_FILE ; then KillTaskWithTimeout fi done echo "Parando hilos de tiempo real" >> $DEBUG_FILE $HALCMD stop echo "Quitando componentes HAL" >> $DEBUG_FILE $HALCMD unload all for i in `seq 10`; do # ( halcmd, en si mismo, es un componente ) if [ `$HALCMD list comp | wc -w` = 1 ]; then break; fi sleep .2 done echo "Quitando modulos HAL_LIB, RTAPI, y Real Time OS" >>$PRINT_FILE $REALTIME stop echo "Quitando segmentos de memoria compartida NML" >> $PRINT_FILE while read b x t x x x x x x m x; do case $b$t in BSHMEM) ipcrm -M $m 2>/dev/null;; esac done < $NMLFILE # Quitar el fichero de bloqueo if [ -f $LOCKFILE ] ; then rm $LOCKFILE fi } ################################################################################ # 4. Hecha la definicion de funciones, la ejecucion continua aqui # Archivo de bloqueo y chequeo; mensajes para rearranque; gestion de Control-c # ################################################################################ # Nombre del archivo de bloqueo para indicar que LinuxCNC está en marcha # Sirve para evitar múltiples copias del controlador LOCKFILE=/tmp/linuxcnc.lock # Chequeo del archivo de bloqueo # Mensajes para arrancar o no un nuevo linuxcnc if [ -f $LOCKFILE ]; then if tty -s; then echo -n "LinuxCNC esta activo. Rearrancarlo? [S/n] " read input; [ -z $input ] && input=s else input=$(@WISH@ < en instalaciones run-in-place, o # /usr/local/share/linuxcnc/configs/ (en instalaciones mediante paquete) cd "$INI_DIR" # Crear el fichero de bloqueo touch $LOCKFILE ################################################################################ # 4.1. Mostar el grafico de introduccion ################################################################################ img=`$INIVAR -ini "$INIFILE" -var INTRO_GRAPHIC -sec DISPLAY 2>>$DEBUG_FILE` imgtime=`$INIVAR -ini "$INIFILE" -var INTRO_TIME -sec DISPLAY 2>>$DEBUG_FILE` if [ "$imgtime" = "" ] ; then imgtime=5 fi if [ "$img" != "" ] ; then if [ -e "$img" ]; then true elif [ -e "$INI_DIR/$img" ]; then img="$INI_DIR/$img" elif [ -e "$LINUXCNC_IMAGEDIR/$img" ]; then img="$LINUXCNC_IMAGEDIR/$img" else img= fi fi if [ "$img" != "" ] ; then if [ -x $LINUXCNC_TCL_DIR/bin/popimage ] ; then $LINUXCNC_TCL_DIR/bin/popimage $img $imgtime & fi fi ################################################################################ # 4.2. Ahora podemos finalmente empezar a cargar ( de verdad) LinuxCNC # Ejecutar servidor linuxcnc (linuxcncsvr) # Arrancar REALTIME. Se arranca con el script /etc/init.d/realtime, al que apunta la variable REALTIME # Exportar la localizacion de los módulos en tiempo real HAL # Ejecutar io en segundo plano si se define en INI # Ejecutar halui # Ejecuta archivos de configuración de HALCMD # Ejecutar comandos discretos HAL # Comienza el ticking para las cosas que corran en tiempo real # Ejecutar tarea en segundo plano # Ejecutar otras aplicaciones # Ejecutar el programa de display en primer plano # El programa de interfaz grafica no volverá a este script hasta que se termine. # En ese momento sera hora de limpiar con la funcion cleanup ################################################################################ # 4.2.1. Ejecutar servidor linuxcnc en segundo plano, siempre (posee/crea los bufers para NML) echo "Arrancando programa servidor de LinuxCNC: $EMCSERVER" >>$PRINT_FILE if ! program_available $EMCSERVER; then echo "No se puede ejecutar el servidor $EMCSERVER" Cleanup exit 1 fi export INI_FILE_NAME="$INIFILE" $EMCSERVER -ini "$INIFILE" & sleep 1 # 4.2.2. Arrancar REALTIME. Se arranca con el script /etc/init.d/realtime echo "Cargando sistema operativo de tiempo real, RTAPI y HAL_LIB" >>$PRINT_FILE if ! $REALTIME start ; then # Fallo en la carga. Limpiar y salir echo "El sistema de tiempo real no se ha cargado" Cleanup exit -1 fi # 4.2.3. exportar la localizacion de los modulos HAL de tiempo real de forma que "halcmd loadrt" los encuentre. # nota: los modulos .ko, para instalacion por paquete, estan en /usr/realtime-3.4-9-rtai-686-pae/modules/linuxcnc export HAL_RTMOD_DIR=$LINUXCNC_RTLIB_DIR # 4.2.4. Correr IO en segundo plano si esta definido en INI if [ "$EMCIO" != "" ] ; then echo "Arrancando programa IO LinuxCNC: $EMCIO" >>$PRINT_FILE if ! program_available $EMCIO ; then echo "No se puede ejecutar programa IO $EMCIO" Cleanup exit 1 fi $HALCMD loadusr -Wn iocontrol $EMCIO -ini "$INIFILE" else echo "Saltando programa IO LinuxCNC IO >>$PRINT_FILE" fi # 4.2.5. Correr halui en segundo plano, si es necesario if [ -n "$HALUI" ] ; then echo "Arrancando programa HAL User Interface: $HALUI" >>$PRINT_FILE if ! program_available $HALUI ; then echo "No se puede ejecutar $HALUI" Cleanup exit 1 fi $HALCMD loadusr -Wn halui $HALUI -ini "$INIFILE" fi TWOPASS=`$INIVAR -ini "$INIFILE" -var TWOPASS -sec HAL -num 1 2> /dev/null` if [ -n "$TWOPASS" ] ; then # si [HAL]TWOPASS se ha definido, manejar todas las entradas [HAL]HALFILE aqui: CFGFILE=/usr/lib/tcltk/linuxcnc/twopass.tcl export PRINT_FILE # twopass puede añadir a PRINT_FILE if ! haltcl -i "$INIFILE" $CFGFILE && [ "$DASHK" = "" ]; then Cleanup exit -1 fi else # 4.2.6. Ejecutar configuracion HALCMD (si la hay) # tomar primer nombre de archivo de configuracion desde ini NUM=1 CFGFILE=`$INIVAR -tildeexpand -ini "$INIFILE" -var HALFILE -sec HAL -num $NUM 2> /dev/null` while [ -n "$CFGFILE" ] ; do IFS='\ ' read CFGFILE CFGFILE_ARGS <<< "$CFGFILE" # separar args foundmsg="" saveIFS=$IFS; IFS=: # dos puntos (:) separador de path para HALLIB_PATH explicit_file_in_hallib=${CFGFILE#LIB:} # separar cabecera 'LIB:' if [ -z "$explicit_file_in_hallib" ] ; then echo "ILLFORMED LIB:file:<$CFGFILE>" fi if [ "$explicit_file_in_hallib" != "$CFGFILE" ] ; then foundfile="$HALLIB_DIR/$explicit_file_in_hallib" if [ ! -r $foundfile ] ; then echo "NO PUEDEO LEER LIB:file:$foundfile" fi foundmsg="Encontrado fichero(LIB): $foundfile" else if [ "${CFGFILE:0:1}" = "/" ] ; then foundfile=$CFGFILE ;# path absoluto foundmsg="Found file(ABS): $foundfile" else for pathdir in $HALLIB_PATH ; do foundfile=$pathdir/$CFGFILE if [ -r $foundfile ] ; then # usar primer fichero encontrado en HALLIB_PATH if [ "${pathdir:0:1}" = "." ] ; then foundmsg="Encontrado fichero(REL): $foundfile" else foundmsg="Encontrado fichero(lib): $foundfile" fi break fi done fi fi [ -d $foundfile ] && foundmsg="" IFS=$saveIFS if [ -z "$foundmsg" ] ; then echo "NO ENCUENTRO FICHERO PARA:$CFGFILE" Cleanup exit -1 fi echo "$foundmsg" CFGFILE="$foundfile" case $CFGFILE in *.tcl) if ! haltcl -i "$INIFILE" $CFGFILE $CFGFILE_ARGS \ && [ "$DASHK" = "" ]; then Cleanup exit -1 fi ;; *) if ! $HALCMD -i "$INIFILE" -f $CFGFILE && [ "$DASHK" = "" ]; then Cleanup exit -1 fi esac # SIGUIENTE FICHERO DEL ini NUM=$(($NUM+1)) CFGFILE=`$INIVAR -tildeexpand -ini "$INIFILE" -var HALFILE -sec HAL -num $NUM 2> /dev/null` done fi # 4.2.7. Ejecutar comandos discretos HAL desde el fichero ini ( si existen) # PRIMER COMANDO DEL INI NUM=1 HALCOMMAND=`$INIVAR -ini "$INIFILE" -var HALCMD -sec HAL -num $NUM 2> /dev/null` while [ -n "$HALCOMMAND" ] ; do if [ -n "$HALCOMMAND" ] ; then echo "Ejecutando comando HAL: $HALCOMMAND" >>$PRINT_FILE if ! $HALCMD $HALCOMMAND && [ "$DASHK" = "" ]; then echo "Comando Hal del ini $HALCOMMAND ha fallado." Cleanup exit -1 fi fi # siguiente comando del ini NUM=$(($NUM+1)) HALCOMMAND=`$INIVAR -ini "$INIFILE" -var HALCMD -sec HAL -num $NUM 2> /dev/null` done # 4.2.8. comienza ticking $HALCMD start # 4.2.9. Correr task en segundo plano echo "Starting TASK program: $EMCTASK" >>$PRINT_FILE if ! program_available $EMCTASK ; then echo "No se puede ejecutar el programa TASK $EMCTASK" Cleanup exit 1 fi # setup LD_PRELOAD if deemed necessary by configure unset LD_PRELOAD if [ -n "$PRELOAD_WORKAROUND" ] ; then export LD_PRELOAD=$PRELOAD_WORKAROUND fi $EMCTASK -ini "$INIFILE" & # 4.2.10. Correr otras aplicaciones run_applications # 4.2.11. Correr display en primer plano echo "Arrancando programa DISPLAY: $EMCDISPLAY" >>$PRINT_FILE result=0 case $EMCDISPLAY in # caso tklinuxcnc o mini tklinuxcnc|mini) # tklinuxcnc y mini estan en el directorio tcl, no en el bin if [ ! -x $LINUXCNC_TCL_DIR/$EMCDISPLAY.tcl ] ; then echo "No se puede ejecutar el programa DISPLAY $LINUXCNC_TCL_DIR/$EMCDISPLAY.tcl $EMCDISPLAYARGS" Cleanup exit 1 fi $LINUXCNC_TCL_DIR/$EMCDISPLAY.tcl -ini "$INIFILE" $EMCDISPLAYARGS result=$? ;; # caso dummy...o display de mentira dummy) # dummy display just waits for echo "DISPLAY MODULO DUMMY, pulse para continuar." read foo; ;; # caso keystick keystick) if ! program_available keystick ; then echo "No puedo ejecutar programa DISPLAY $EMCDISPLAY $EMCDISPLAYARGS $EXTRA_ARGS" Cleanup exit 1 fi if [ ! -z "$DISPLAY" ]; then xterm -xrm 'XTerm*metaSendsEscape:false' -ls -e keystick -ini "$INIFILE" else keystick -ini "$INIFILE" fi result=$? ;; # el resto de displays are assumed to be commands on the PATH *) if ! program_available $EMCDISPLAY; then echo "No puedo ejecutar programa DISPLAY $EMCDISPLAY $EMCDISPLAYARGS $EXTRA_ARGS" Cleanup exit 1 fi $EMCDISPLAY -ini "$INIFILE" $EMCDISPLAYARGS $EXTRA_ARGS result=$? ;; esac ########################################################################## # 5. El display no regresa hasta que se apague # es momento de limpieza ########################################################################## Cleanup exit $result