# [SCRIPTS DE SHELL] Estoy creando un actualizador (abierto)

## sefirotsama

Tengo demasiadas dudas respecto la nomenclatura de los comandos en el script de shell... Alguien me sabe decir de alguna guia o tutorial? Estoy siguiendo un libro muy viejo de linux en el que hay ejemplos que se ejecutan en !/bin/csh y... no funciona

Pretendo hacer un actualizador automático que lleve a cabo las acciones que hago usualmente por separado.

Como debo hacer para asignar un valor a una variable?

Necesito uno variable entera que es la salida de un comando.

Adjunto el script que estoy haciendo (está muy verde):

```
#SCRIPT ACTUALITZADOR

URL_PING="http://www.gentoo.org"

clear

echo -e "\n\n\tSYNCRONITZADOR DOWNLOADER\n\t

----------

## ekz

Yo aprendí lo básico con esta, http://www.etxea.net/docu/taller_bash/bash.html

por si está caído, Googlecache

SAludos

----------

## sefirotsama

Tu link no me iva... he estado ojeando esto:

http://es.tldp.org/COMO-INSFLUG/COMOs/Bash-Prog-Intro-COMO/

A ver que saco de ahí... hasta la semana que viene que no me conecte ya diré algo...

----------

## pcmaster

No sé si habrá sido al transcribir tu script en el foro, pero me da la impresión de que intentgas poner una orden que ocupa varias líneas.

Te recuerdo que cada línea de bash debe ocupar eso, una línea, sin retornos de carro por medio. Por larga que sea. No sé que editor estás usando pero te recomiendo vim.

Si a pesar de todo necesitas que una orden ocupe varias líneas, debes poner al final de cada línea el carácter \

Por ejemplo:

echo -e "Opciones:\n" \

"1- Entrar\n" \

"2- Salir\n" \

"3- Abrir\n" \

"4- Cerrar\n"

Asignar un valor a una variable y después usarlo:

VARIABLE="JAMON"

VARIABLE="Un $VARIABLE serrano"

echo $VARIABLE

Manuales: buscando por manual bash script en google aparecen muchos, como este:

http://xinfo.sourceforge.net/documentos/bash-scripting/bash-script-2.0.html

o el de la wikipedia:

http://es.wikipedia.org/wiki/Bash

----------

## jgascon

 *sefirotsama wrote:*   

> 
> 
> Como debo hacer para asignar un valor a una variable?
> 
> 

 

Por lo que veo que intentas hacer aquí:

```

network=('ping -c 3 $URL_PING|grep -cv unknow') 

```

creo que lo que intentas hacer es asignar la salidad de una orden a una variable, (corrígeme si me equivoco). Hay dos formas de hacerlo:

1.- Mediante los acentos graves (backquotes en inglés) -> `` 

```

network=`ping -c 3 $URL_PING|grep -cv unknow`

```

2.- Mi favorita, porque es más clara y no se confunde con las comillas simples, el dólar paréntesis -> $()

```

network=$(ping -c 3 $URL_PING|grep -cv unknow) 

```

En cuanto a una guía para programar en bash yo siempre consulto Advanced Bash-Scripting Guide aunque está en inglés y creo que no está traducida.

----------

## sefirotsama

Lo de las lineas lo dices por:

```
time su -c "emerge --sync && layman --sync-all &&cd /usr/portage &&svn co

http://overlays.gentoo.org/svn/dev/dang/maintainer && svn cohttp://overlays.gentoo.org/svn/dev/dang/user &&

eclean --destructive distfiles && eclean --destructive packages &&emerge --color y -vf world && update-eix" 
```

Necesitaria que fuera una sola linea para no haber de poner 33 veces el password del root (y hacerlo desatendido). Por eso encadeno los comandos con && dentro del su -c

aparte...

si pretendo hacer algo como

$VARIABLE="less archivo.txt|grep \"error\""

Y me coja solo la salida de grep (que e slo que haria si lo ejectuto), entonces que?

Bueno me voy que el portatil se queda sin bateria.

Nos vemos!

(espero que de aqui unos dias tenga hecho algo, y lo postearia).[/b]

----------

## ekz

 *sefirotsama wrote:*   

> 
> 
> Necesitaria que fuera una sola linea para no haber de poner 33 veces el password del root (y hacerlo desatendido). Por eso encadeno los comandos con && dentro del su -c
> 
> 

 

No usas sudo?

(Y añadí el link a google cache del link)

SAludos!

----------

## pcmaster

 *sefirotsama wrote:*   

> Lo de las lineas lo dices por:
> 
> ```
> time su -c "emerge --sync && layman --sync-all &&cd /usr/portage &&svn co
> 
> ...

 

Me refería a una sola linea con el editor de texto, es decir, que mientras escribes todo eso NO pulses la tecla intro. La línea puede ser todo lo larga que quieras. Si quieres pulsar intro para dividirla, ya te he explicado cómo hacerlo con el caracter \

 *sefirotsama wrote:*   

> 
> 
> aparte...
> 
> si pretendo hacer algo como
> ...

 

Esa línea está mal. Lo que pretendes hacer sería:

VARIABLE=`cat archivo.txt|grep \"error\"`

lo que haría esta orden es, de todo el contenido del archivo.txt, seleccionar las líneas que contengan la palabra error entre comillas, encadenarlas y meterlas en la variable VARIABLE.

Tu linea tenía varios errroes: una variable no lleva el $ para asignarle el valor, sino sólo para leerlo, less es interactivo, o sea que no sirve, 

recuerda que el ` se hace con el acento abierto (tecla de al lado de la p en un teclado español) y la barra espaciadora. El " son las comillas normales que hay en la tecla del 2, encima de la q y la w.

Si cada línea que contuviera "error" tuviese que procesarse por separado, sería preferible algo así:

for LINEA in `cat archivo.txt|grep \"error\"`; do

 echo $LINEA

done

hace poco he puesto un par de hilos donde explico unos scripts que he realizado. Puedes echarles un vistazo para ver cómo están hechos:

https://forums.gentoo.org/viewtopic-t-574118.html

https://forums.gentoo.org/viewtopic-t-573062.html

----------

## achaw

Tambien esta en portage:

```
emerge app-doc/abs-guide
```

La guia "absoluta" de bash, completisima y con ejemplo...en ingles.

La uso desde que uso GNU/Linux...   :Very Happy: 

Una correccion:

```

for LINEA in `cat archivo.txt|grep \"error\"`; do

echo $LINEA

done
```

Por:

```

for LINEA in `grep \"error\" archivo.txt`; do

echo $LINEA

done
```

Saludos

----------

## pcmaster

Me lo apunto  :Wink: 

----------

## i92guboj

```

for LINEA in `grep \"error\" archivo.txt`; do

echo $LINEA

done
```

Mmm, no estoy muy pendiente del hilo, así que no se si esto es como ejemplo o es parte del script, pero el efecto de ese bucle sería exactamente el mismo que el de un simple 

```
$ grep \"error\" archivo.txt
```

En cuanto a lo demás, el script del primer post no es un script de bash válido por varias razones, quizás sea un script para algún otro shell, no estoy familiarizado más que con bash y el sh estándar de unix, pero por la sintaxis, a primera vista creo que podría ser un script de csh.

No hay grandes diferencias, la Advanced Bash scripting guide (a pesar del nombre) es válida para todos los niveles, y está ilustrada con montones de ejemplos de todos los niveles, es una obra indispensable tanto para aprender como para cosas más avanzadas.

Una nota sobre este if:

```

if ($network == 0)

{

        echo -e "\nSembla que la xarxa funciona correctament\n...\n"

        sleep 2

        echo -e "^[[31;01mContrasenya del root?^[[39;49;00m"

        time su -c "emerge --sync && layman --sync-all &&cd /usr/portage &&svn co

http://overlays.gentoo.org/svn/dev/dang/maintainer && svn cohttp://overlays.gentoo.org/svn/dev/dang/user &&

eclean --destructive distfiles && eclean --destructive packages &&emerge --color y -vf world && update-eix"

} 

```

La condición se puede simplificar, simplemente chequea el valor de la variable, si es cero, entonces la condición es cierta, esto simplifica los chequeos en bash bastante, además, en bash correcto, sería con corchetes (la condición). El bloque se abre con if y se cierra con fi, y un comando se parte en varias líneas con \, lo cual además nos da una estructura más comprensible en el script:

```

if [ $network ]

then

        echo -e "\nSembla que la xarxa funciona correctament\n...\n"

        sleep 2

        echo -e "^[[31;01mContrasenya del root?^[[39;49;00m"

        time su -c "emerge --sync && \

                layman --sync-all && \

                cd /usr/portage && \

                svn co http://overlays.gentoo.org/svn/dev/dang/maintainer && \

                svn cohttp://overlays.gentoo.org/svn/dev/dang/user && \

                eclean --destructive distfiles && \

                eclean --destructive packages && \

                emerge --color y -vf world && \

                update-eix"

fi

```

Ya te lo han dicho más arriba, pero para ejecutar algo 'inline', necesitas $() o bien backquotes -> `comando`

Yo prefiero la sintaxis de los paréntesis, porque es más clara. Los backquotes se pueden confundir con comillas simples, cuyo significado en un script es muy distinto.

----------

## pcmaster

 *i92guboj wrote:*   

> 
> 
> ```
> 
> for LINEA in `grep \"error\" archivo.txt`; do
> ...

 

Evidentemente. Sólo se lo ponía a modo de ejemplo sobre cómo tratra cada linea por separado en un script. El echo podría ser otra orden mas compleja, o varias.

----------

## sefirotsama

Agradezco todas las respuestas y, además emergeré la guia en cuestión.

De ehcho me lancé a "programar" sin pensarme lo mucho. Gracias a todos, de verdad.

A medida que vaya progresando o me salgan dudas os postearé!!!

Y si cuando esté acabado a alguien le interesa el script pues lo colgaré (sera tipo menu, opción 1 descargar fuentes y paquetes, opción 2 instalar, opción 3 todo lo anterior).

Kuroo y otros programas no me han convencido NADA y con algo sencillito estoy contento.

Aprovechando... alguien sabe como debo hacerlo para colorear las linias de texto?? Cuando hago un emerge --color y hay colorines y eso pues, mola, xD

----------

## jgascon

Puedes usar este script para colorear la salida de muchas ordenes. Por ejemplo, para la salida de un tail:

```

tail -f /var/log/messages | colorlog.pl

```

Pero sirve para colorear cualquier cosa:

```

cat archivo.txt | colorlog.pl

```

Y si el archivo es muy largo:

```

cat archivo_muy_largo.txt | colorlog.pl | less

```

----------

