Shell script: programas externos, E/S y dirección de shell


Bash , c-shell  o simplemente shell scripting es  un lenguaje de script  creado a fines de la década de 1980 por un programador llamado Brian Fox, que trabajaba para la Free Software Foundation . Fue pensado como una alternativa de software libre para el shell Bourne (de hecho, su nombre es un acrónimo de Bourne Again SHell ), e incorpora todas las características de ese shell, así como nuevas características como la aritmética de enteros y el control de trabajo

Bash es un “shell de Unix”, es decir  una interfaz de línea de comandos para interactuar con el sistema operativo por lo que está ampliamente disponible, siendo el shell predeterminado en muchas distribuciones de GNU / Linux y en Mac OSX, con puertos existentes para muchos otros sistemas.

En post anteriores hemos hablado en una primera aproximación  al lenguaje c-sheall  con el primer ejemplo famoso de  Hello world y avanzando comandos ,tuberías ,variables ,parámetros y salidas posibles y en un segundo post  sobre el  uso de las Tuberías , sustitución de comandos,operadores ,asignación de variables ,Bucles , literales , variables   y aritmética no entera

Asimismo   en un  post  anterior continuamos  avanzando en el conocimiento de este lenguaje con el uso de las funciones, subshells  y las  variables de entorno

En esta ocasión vamos a ver el uso de funciones de shell, funciones de e/s y la redirección shell

close up code coding computer

 

 

 

Funciones de shell 

Programas externos

Bash, como un shell, es en realidad un lenguaje de «pegamento». Ayuda a los programas a cooperar entre sí, y se beneficia de ello. Siempre busque en Internet lo que desea: hay muchas utilidades de línea de comandos disponibles.

Usando whiptail 

Whiptail es un programa que permite que los scripts de shell muestren cuadros de diálogo al usuario con fines informativos, o para obtener información del usuario de manera amigable. Whiptail se incluye de forma predeterminada en Debian y en varias otras distribuciones de GNU / Linux.

Desde el diccionario GNU / Linux : whiptail es un reemplazo de «diálogo» que usa newt en lugar de ncurses.
Desde su README: whiptail está diseñado para ser compatible con el cuadro de diálogo (1), pero tiene menos funciones: algunos cuadros de diálogo no están implementados, tales como caja de cola, caja de tiempo, caja de calendario, etc.

Usando man, info y ayuda 

Estos tres programas son donde puede encontrar ayuda o referencia de. man muestra las páginas de manual de roff , la información muestra las documentaciones de texinfo, mientras que la ayuda muestra las ayudas integradas.

Al añadir --long-ayuda , --help o --usage a un programa de línea de comandos puede también le da la información de uso. Posibles sinónimos incluyen -H y -h .

Solo prueba estos:

man --help
man man

info --help
man info
info info

help help

Presionar h en las interfaces de man and info también puede darle alguna dirección.

Entrada / Salida

La lectura incorporada 

De la ayuda leída :

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]

Lea una línea de la entrada estándar y divídala en campos. La lectura es excelente tanto para las entradas del usuario como para la lectura de entradas / tuberías estándar.

Un ejemplo de entrada de usuario:

 # 'readline' pronuncie el nombre de la variable predeterminada 
read -e -p "Haga esto:" -i "destruye el  comando " commmand

echo  "$command "

O incluso más simple:

pause ()  {  read -n 1 -p "Presione cualquier tecla para continuar ..."  ;  }

Ejemplo de nivel de Hola-mundo de la operación stdout:

 echo  'Hola mundo!'  | {  read hola
 echo  $hola  }

Solo se creativo. Por ejemplo, en muchos sentidos, leer puede reemplazar el látigo. Aquí hay un ejemplo, extraído del script de shell de Arthur200000 :

# USAGE 
# yes_or_no "title" "text" width ["yes text"] ["no text"] 
# INPUTS 
# $ LINE = (y / n) - Si debemos usar el estilo de entrada basado en líneas (lectura) 
# $ _DEFAULT = (opcional) - El valor predeterminado para leer yes_or_no ()  { 
yes_or_no() {
  if [ "$LINE" == "y" ]; then
    echo -e "\e[1m$1\e[0m"
    echo '$2' | fold -w $4 -s
    while read -e -n 1 -i "$_DEFAULT" -p "Y for ${5:-Yes}, N for ${6:-No}[Y/N]" _yesno; do
      case $_yesno in
        [yY]|1)
          return 0
          ;;
        [nN]|0)
          return 1
          ;;
        *)
          echo -e "\e[1;31mINVALID INPUT\x21\e[0m"
       esac
  else whiptail --title "${1:-Huh?}" --yesno "${2:-Are you sure?}" ${3:-10} ${4:-80}\
         --yes-button "${5:-Yes}" --no-button "$6{:-No}"; return $?
  fi
}
# USAGE  # user_input var_name ["title"] ["prompt"] [altura] [ancho] 
 # ENTRADAS  # $ LINE = (y / n) - Si debemos usar el estilo de entrada basado en líneas (lectura) 
 # $ _DEFAULT = ( opcional) - El valor predeterminado para leer; por defecto a nada. user_input () 
user_input(){
  if [ "$LINE" == "y" ]; then
    echo -e "\e[1m${2:-Please Enter:}\e[0m" | fold -w ${4:-80} -s
    read -e -i "${_DEFAULT}" -p "${3:->}" $1
  else
    eval "$1"=$(whiptail --title "$2" --inputbox "$3" 3>&1 1>&2 2>&3)
  fi
}
 

Redirección de shell 

En shells, la redirección se usa para la E / S de archivos. El uso más común de es redirigir secuencias estándar (stdin, stdout y stderr) para aceptar la entrada de otro programa a través de tuberías, para guardar la salida del programa como un archivo, y para suprimir la salida del programa redireccionando una secuencia a / dev / null .

Índice de símbolos 

Símbolo Explicación
!
  • Lógicamente niega el estado de salida de una tubería. Por ejemplo, si grep YES votes.txt devuelve 0 , entonces ! grep YES votes.txt devuelve 1 , pero de lo contrario es equivalente.
  • También soportado por el [...] builtin, y dentro de expresiones condicionales. Por ejemplo, si [[-e file.txt]] es verdadero, entonces [[! -e archivo.txt]] es falso.
  • También se admite en expresiones aritméticas. Por ejemplo, si $ i es distinto de cero, entonces $ ((! I)) es 0 .
  • Vea también #! abajo.
"..."
  • Cita un argumento (o parte de un argumento) para que no esté dividido por espacios en blanco en múltiples argumentos, pero sin impedir la expansión de parámetros y la sustitución de comandos internamente.
  • Véase también $ "..." a continuación.
#
  • Introduce un comentario (que continúa hasta el final de la línea). Por ejemplo, el comando foo bar baz # bip es equivalente al comando foo bar baz , porque el comentario # bip se elimina.
  • Dentro de una expresión aritmética, un literal entero de la forma b # n se interpreta en la base b . Por ejemplo, 2 # 110110 es binario 110110, es decir, cincuenta y cuatro.
  • Vea también #! abajo.
  • Véase también $ # abajo.
#!
  • (Por lo general, » shebang » cuando se lee en voz alta). Se usa al comienzo de un script ejecutable para especificar el intérprete que se debe usar para ejecutarlo. Por ejemplo, si la primera línea de script.pl es #! / Usr / bin / perl , y script.pl tiene permisos ejecutables, entonces ./script.pl es aproximadamente equivalente a / usr / bin / perl ./script.pl .
  • La primera línea de un script Bash generalmente es #! / Bin / bash o #! / Bin / sh . (El primero generalmente se considera preferible.)
PS
  • Introduce varios tipos de expansiones, especialmente la expansión de parámetros (como en var o $ { var } ), la sustitución de comandos (como en $ ( comando ) ) y la expansión aritmética (como en $ (( expresión )) ).
PS
  • Una variante de "..." (ver más arriba) que admite la traducción específica del entorno local. (A menos que esté escribiendo scripts para su uso en varios idiomas, por ejemplo, inglés y francés, no debe preocuparse por esto).
PS
  • El número de parámetros posicionales (argumentos de un script o función). Por ejemplo, si se invoca un script como script.sh abc , entonces $ # será 3 . Los elementos incorporados que modifican los parámetros posicionales, como shift y set , también afectan a $ # .
% El operador de módulo. Devuelve el resto resultante de la división entera. Ej. 5% 2 = 1
Y Ampersand Comúnmente se utiliza para iniciar un comando en el fondo. Ej. Firefox &
' Una frase. Se utiliza para citar texto literalmente.
( Paréntesis abiertos. Se utiliza para denotar el comienzo de una subshell, entre otras cosas.
) Paréntesis de cierre. Se utiliza para denotar el «EOF» de una subshell.
* Asterisco. Denota multiplicación. Ej. 5 * 2 = 10
+ Más.Denota la suma. Ej. 5 + 2 = 7
, Coma. Utilizado para la separación. Ej. Archivo ls {1,2,3}
- Guión. Denota la resta. Ej. 5-2 = 3
. Parada completa.
/ Barra inclinada. Indica división entera (por ejemplo, 5/2 = 2) o parte de una ruta (por ejemplo, / home / usuario)
: Colon.
; Punto y coma. Separa las líneas si no existe una nueva línea / EOL. Ej. Echo hola; mundo eco
< Soporte de ángulo abierto. Utilizado para la redirección de entrada
= Signo de igualdad Se utiliza para asignar variables y comprobar la igualdad.
> Ángulo de cierre del soporte. Se utiliza para la redirección de salida.
? Signo de interrogación.
@ A la señal. Normalmente se utiliza como una variable que contiene todos los argumentos pasados ​​al entorno como $ @
El Abra el corchete. Utilizado como una alternativa visualmente más atractiva para probar. Por ejemplo, si [condición]; entonces etc
\ Barra invertida Más comúnmente utilizado para escapar. Por ejemplo, archivo rm \ con \ a \ manojo \ de \ espacios.txt
] Cierre corchete. Cierra los recintos de prueba.
^ Signo de intercalación.
_ Guion bajo.
`…`
  • Activa la sustitución de mando; equivalente a $ (…) , pero es algo más propenso a errores.
{ Abra el apoyo rizado. Utilizado para expansión de variable específica. Por ejemplo, (donde var = «hola») echo «$ {var} world» imprimirá «hola mundo», echo «$ varworld» generará un error, esperando una variable llamada varworld.
| Tubo. Se utiliza para redireccionar la entrada a la salida. Específicamente, toma la salida del comando en el lado izquierdo, ejecuta el programa en el lado derecho y luego pasa el contenido de la salida del primer comando al segundo, como si se estuviera escribiendo desde un teclado. ‘ls -l | grep Desk ‘es equivalente a ejecutar «grep Desk», y luego escribir manualmente lo que ls -l tendría salida. Cada vez que se presiona la tecla de retorno, se activará grep hasta que se presione ^ D para pasar el EOF.
} Cierre corsé.
~ Tilde. Normalmente se utiliza para referirse al directorio de inicio. Registrado como «mrwhite», cd ~ (o simplemente cd) iría a / home / mrwhite. Al iniciar sesión como otro usuario, se podría lograr el mismo efecto con ‘cd ~ mrwhite’.

Enlaces externos en ingles

Shell scripting : variables y operaciones


Bash , c-shell  o simplemente shell scripting es  un lenguaje de script  creado a fines de la década de 1980 por un programador llamado Brian Fox, que trabajaba para la Free Software Foundation . Fue pensado como una alternativa de software libre para el shell Bourne (de hecho, su nombre es un acrónimo de Bourne Again SHell ), e incorpora todas las características de ese shell, así como nuevas características como la aritmética de enteros y el control de trabajo

Bash es un «shell de Unix», es decir  una interfaz de línea de comandos para interactuar con el sistema operativo por lo que está ampliamente disponible, siendo el shell predeterminado en muchas distribuciones de GNU / Linux y en Mac OSX, con puertos existentes para muchos otros sistemas.

Además del modo interactivo, donde el usuario escribe un comando a la vez, con ejecución y respuesta inmediatas, Bash (como muchos otros shells) también tiene la capacidad de ejecutar un script completo de comandos, conocido como «Bash shell script» (o «Bash script» o «shell script» o simplemente «script»)  que es justo   lo que vamos a tratar en este post como continuación de un  post anterior introductorio donde exponimos ale tipico Hello world en c-shell

close up code coding computer

Tuberías y sustitución de comandos 

Como hemos visto, el valor de retorno de un comando, tomado estrictamente, es solo un pequeño entero no negativo destinado a indicar el éxito o el fracaso. Su salida real es lo que escribe en el flujo de salida estándar. De forma predeterminada, el texto escrito en el flujo de salida estándar se imprime en el terminal, pero hay algunas formas en que se puede «capturar» y usar como el verdadero valor de retorno del comando.

Tuberías 

Cuando una secuencia de comandos se vincula entre sí en una tubería, la salida de cada comando se pasa como entrada al siguiente. Esta es una técnica muy poderosa, ya que nos permite combinar varios programas de utilidad pequeños para crear algo complejo.

Sustitución de comandos 

La sustitución de comandos es un poco como expansión de variable, pero ejecuta un comando y captura su salida, en lugar de simplemente recuperar el valor de una variable. Por ejemplo, considere nuestro ejemplo de get_password anterior:

#! / bin / bash

función get_password (  ) 
# Uso: get_password VARNAME 
#Le pide al usuario una contraseña; lo guarda como $ VARNAME.
# Devuelve un estado de salida distinto de cero si la entrada estándar no #es un terminal, o si el comando  "leer" devuelve un estado de salida #tinto de cero.
{
  if [[ -t 0 ]] ; then
    read -r -p 'Password:' -s "$1" && echo
  else
    return 1
  fi
}
 
get_password PASSWORD && echo "$PASSWORD"

Realmente no hay razón para que la persona que llama deba guardar la contraseña en una variable.

Si get_password simplemente imprimió la contraseña en su salida estándar, entonces la persona que llama podría usar la sustitución de comandos y usarla directamente:

 #! / bin / bash
 
función get_password (  ) 
# Uso: get_password 
# Pide al usuario una contraseña; Imprime para capturar llamando al código. 
# Devuelve un estado de salida distinto de cero si la entrada estándar no es un terminal, o si 
# salida estándar * es * un terminal, o si el comando "leer" devuelve un 
estado de salida distinto de cero #.
 {
  if [[ -t 0 ]] && ! [[ -t 1 ]] ; then
    local PASSWORD
    read -r -p 'Password:' -s PASSWORD && echo >&2
    echo "$PASSWORD"
  else
    return 1
  fi
}
 
echo "$(get_password)"

Para evaluar "$ (get_password)" , Bash ejecuta el comando get_password en una subshell, capturando su salida estándar y reemplaza $ (get_password) por la salida capturada.

Además de la notación $ (...) , también se admite una notación más antigua  (con comillas inversas), y aún se encuentra con bastante frecuencia. Las dos notaciones tienen el mismo efecto, pero la sintaxis de  es más restrictiva y, en casos complejos, puede ser más complicado acertar.

La sustitución de comandos permite anidar como vemos .  Se permite, expresiones  "$ (b" $ (c) ")" . (es decir ,ejecuta el comando c , usando su salida como un argumento para b , y usando la salida de eso como un argumento para a .)

Una sustitución de comando puede contener una secuencia de comandos, en lugar de un solo comando de modo que se captura la salida de todos estos comandos.

Como hemos visto anteriormente, se pueden usar puntos y coma en lugar de líneas nuevas para separar los comandos, lo cual  es particularmente común en la sustitución de comandos.

Una sustitución de comando puede incluso contener asignaciones de variables y definiciones de funciones (aunque, como los comandos sustituidos se ejecutan dentro de una subshell, las asignaciones de variables y las definiciones de funciones dentro del comando no se verán fuera de ella; solo son útiles si se usan dentro de los comandos sustituidos ).

Aritmética de shell 

Las expresiones aritméticas en Bash se modelan estrechamente en las de C, por lo que son muy similares a las de otros lenguajes derivados de C, como C ++, Java, Perl, JavaScript, C # y PHP.

Una diferencia importante es que Bash solo admite aritmética de enteros (números enteros), no aritmética de punto flotante (decimales y fracciones); Por ejemplo  algo como 3 + 4 significa lo que esperarías (7), pero algo como 3.4 + 4.5 es un error de sintaxis. Algo así como 13/5 está bien, pero realiza una división de enteros, por lo que se evalúa en 2 en lugar de en 2.6.

Expansión aritmética 

Quizás la forma más común de usar expresiones aritméticas es en la expansión aritmética , donde el resultado de una expresión aritmética se usa como un argumento para un comando

. La expansión aritmética se denota $ ((...)) . Por ejemplo, este comando:

 echo  $ ((  3  +  4  *  (  5  -  1  )  ))

impresiones 19 .

expr (en desuso) 

Otra forma de usar expresiones aritméticas es mediante el programa Unix «expr», que era popular antes de que Bash admitiera las matemáticas.  Similar a la expansión aritmética, este comando:

 echo  ` expr 3 + 4  \ *  \ (  5 - 1  \)  `

impresiones 19 .

Tenga en cuenta que el uso de «expr» requiere un carácter de escape «\» antes del operador de multiplicación «*» y los paréntesis. Tenga en cuenta los espacios entre los símbolos de cada operador, incluidos los paréntesis.

Operadores numéricos

Además de las notaciones familiares + (adición) y - (resta), las expresiones aritméticas también son compatibles con * (multiplicación), / (división entera, descrita anteriormente), % (división de módulo, la operación «resto»; por ejemplo, 11 dividido por 5 es 2 el resto 1, entonces 11% 5 es 1 ), y ** («exponenciación», es decir, involución; por ejemplo, 2 4 = 16, entonces 2 ** 4 es 16 ).

Los operadores + y - , además de sus sentidos «binarios» (dos operandos) de «suma» y «resta», tienen sentidos «unarios» (un operando) de «positivo» y «negativo». Unary + tiene básicamente ningún efecto; unary - invierte el signo de su operando. Por ejemplo, - (3 * 4) evalúa a -12 , y - (- (3 * 4)) evalúa a 12 .

Referente a variables 

Dentro de una expresión aritmética, se puede hacer referencia a las variables de shell directamente, sin usar expansión variable (es decir, sin el signo de dólar $ ).

Por ejemplo, esto:

 i  =  2 +3
 echo  $ ((  7  * i ))

impresiones 35 . (Tenga en cuenta que primero se evalúa i , que produce 5 y luego se multiplica por 7. Si hubiéramos escrito $ i en lugar de i , se habría realizado una mera sustitución de cadenas; 7 * 2 + 3 es igual a 14 + 3, es decir, 17 – Probablemente no sea lo que queremos.

El ejemplo anterior se muestra usando «expr»:

 i  =  ` expr 2 + 3  ' 
eco  ' expr 7  \ *  $ i  `

impresiones 35 .

Asignación a variables 

Las variables de shell también se pueden asignar dentro de una expresión aritmética. La notación para esto es similar a la asignación de variables regulares, pero es mucho más flexible.

Por ejemplo, el ejemplo anterior podría reescribirse así:

 echo  $ ((  7  *  (  i  =  2  +  3  )  ))

excepto que esto establece $ i a 5 en lugar de a 2 + 3 .

Tenga en cuenta que, aunque la expansión aritmética parece un poco a la sustitución de comandos, se no se ejecuta en un subnivel; este comando realmente establece $ i a 5 , y los comandos posteriores pueden usar el nuevo valor. (Los paréntesis dentro de la expresión aritmética son solo el uso matemático normal de paréntesis para controlar el orden de las operaciones).

Además del operador de asignación simple = , Bash también admite operadores compuestos como + = , - = , * = , / = y % = , que realizan una operación seguida de una asignación. Por ejemplo, ((i * = 2 + 3)) es equivalente a ((i = i * (2 + 3))) . En cada caso, la expresión en su conjunto se evalúa al nuevo valor de la variable; por ejemplo, si $ i es 4 , entonces ((j = i * = 3)) establece tanto $ i como $ j en 12 .

Por último, Bash soporta operadores de incremento y decremento.

El operador incremental ++ incrementa el valor de una variable en 1; si precede al nombre-variable (como el operador «pre-incremento»), entonces la expresión se evalúa al nuevo valor de la variable , y si sigue al nombre-variable (como el operador «post-incremento»), entonces la expresión se evalúa al valor antiguo de la variable .

Por ejemplo, si $ i es 4 , entonces ((j = ++ i)) establece tanto $ i como $ j en 5 , mientras que ((j = i ++)) establece $ i en 5$ j a 4 . El operador de disminución - es exactamente el mismo, excepto que disminuye el valor de la variable en 1. La reducción previa y posterior de la reducción son completamente análogas al incremento previo y al incremento posterior.

Las expresiones aritméticas como sus propios comandos 

Un comando puede consistir completamente en una expresión aritmética, usando cualquiera de las siguientes sintaxis:

 ((  i  =  2 + 3  ))
 let  'i = 2 + 3'

Cualquiera de estos comandos establecerá $ i en 5 . Ambos estilos de comando devuelven un estado de salida de cero («exitoso» o «verdadero») si la expresión se evalúa como un valor distinto de cero, y un estado de salida de uno («falla» o «falso») si la expresión se evalúa como cero. Por ejemplo, esto:

 ((  0  ))  ||  echo zero
 ((  1  ))  &&  echo non-zero

imprimirá esto:

zero
non-zero

La razón de este comportamiento contraintuitivo es que en C, cero significa «falso» y los valores distintos de cero (especialmente uno) significan «verdadero». Bash mantiene ese legado dentro de las expresiones aritméticas, luego lo convierte en la convención habitual de Bash al final.

El operador de coma 

Las expresiones aritméticas pueden contener múltiples sub-expresiones separadas por comas , . El resultado de la última sub-expresión se convierte en el valor general de la expresión completa. Por ejemplo, esto:

 echo  $ ((  i  =  2 , j  =  2  + i, i * j ))

establece $ i en 2 , establece $ j en 4 e imprime 8 .

De hecho , la función incorporada admite múltiples expresiones directamente sin necesidad de una coma; por lo tanto, los siguientes tres comandos son equivalentes:

 ((  i  =  2 , j  =  2 + i, i * j ))
 let  'i = 2, j = 2 + i, i * j'
 let  'i = 2'  'j = 2 + i'  'i * j'

Operadores de comparación, booleanos y condicionales 

Las expresiones aritméticas son compatibles con los operadores de comparación de enteros < , > , <= (significado ≤), > = (significado ≥), == (significado =) y ! = (Significado). Cada uno evalúa a 1 para «verdadero» o 0 para «falso».

También son compatibles con los operadores booleanos:

  • && («and»), que se evalúan como 0 si cualquiera de sus operandos es cero, y 1 de lo contrario;
  •  ||(«or»), que se evalúa en 1 si alguno de sus operandos es distinto de cero, y en 0 en caso contrario;
  • ! («not»), que se evalúa en 1 si su operando es cero, y en 0 en caso contrario.

Aparte de que utilizan cero para significar valores «falsos» y valores distintos de cero para significar «verdaderos», son como los operadores && , || , y ! que hemos visto fuera de expresiones aritméticas. Al igual que esos operadores, estos son operadores «abreviados» que no evalúan su segundo argumento si su primer argumento es suficiente para determinar un resultado. Por ejemplo, (((i = 0) &&(j = 2))) no evaluará el (j = 2)parte, y por lo tanto no establecerá $ j en 2 , porque el operando izquierdo de && es cero («falso»).

¿Y soportan el operador condicional b ? e1 : e2 . Este operador evalúa e1 y devuelve su resultado, si b es distinto de cero; de lo contrario, evalúa e2 y devuelve su resultado.

Estos operadores se pueden combinar de formas complejas:

 ((  i  =  (  ( a> b && c <d + e ||  f  == g + h ) ? j: k )  ))

Aritmética de bucles 

Arriba, vimos un estilo de for-loop, que se veía así:

# imprimir todos los enteros del 1 al 20: 
for i in {1..20} ; do
  echo $i
done

Bash también admite otro estilo, modelado en los bucles for de C y lenguajes relacionados, usando aritmética de shell:

# imprimir todos los enteros del 1 al 20: 
for (( i = 1 ; i <= 20 ; ++i )) ; do
  echo $i
done

Este bucle for utiliza tres expresiones aritméticas separadas, separadas por punto y coma (y no comas , son expresiones completamente separadas, no solo subexpresiones):

  • La primera es una expresión de inicialización, se ejecuta antes de que comience el bucle.
  • El segundo es una expresión de prueba; se evalúa antes de cada posible iteración del bucle (incluida la primera), y si se evalúa a cero («falso»), entonces el bucle sale.
  • El tercero es una expresión de conteo; Se evalúa al final de cada iteración de bucle. En otras palabras, este bucle for es exactamente equivalente a este bucle while:
# imprimir todos los enteros del 1 al 20: 
(( i = 1 ))
while (( i <= 20 )) ; do
  echo $i
  (( ++i ))
done

pero, una vez que se acostumbre a la sintaxis, se hace más claro lo que está sucediendo.

Operadores bitwise 

Además de aritméticas y booleanas operadores regulares, Bash también ofrece a los operadores bit a bit «», significa que los operadores que operan sobre números enteros qua cadenas de bits en lugar de qua enteros.

Si aún no está familiarizado con este concepto, puede ignorarlo de manera segura.

Al igual que en C, los operadores bitwise son :

  • & (bitwise «and»),
  • (bitwise «or»),
  • ^ (bitwise «exclusive or»),
  • ~ (bitwise «not»),
  •  << (desplazamiento a la izquierda en modo bit), y
  • >> (desplazamiento a la derecha en modo bit), así como
  •  & =
  •  | =
  • ^ = (que incluyen la asignación, al igual que + = ).

Literales enteros 

Una constante entera se expresa como un entero literal . Ya hemos visto muchos de estos; 34 , por ejemplo, es un literal entero que denota el número 34.

Todos los ejemplos anteriores  han sido decimales (base diez) literales enteros, que es el valor predeterminado; pero, de hecho, los literales pueden expresarse en cualquier base en el rango 2–64, utilizando el valor de base de notación # (la propia base se expresa en base diez).

Por ejemplo, esto:

 echo $ (( 12 )) # usa el valor predeterminado de base diez (decimal)
 echo $ (( 10 # 12 )) # especifica explícitamente base diez (decimal)
 echo $ (( 2 # 1100 )) # base dos (binario)
 echo $ (( 8 # 14 )) # base ocho (octal)
 echo $ (( 16 # C )) # base dieciseis (hexadecimal)
 eco $ (( 8 + 2 # 100 )) # ocho en base diez (decimal), más cuatro en base dos (binario)

Imprimirá 12 seis veces. (Tenga en cuenta que esta notación solo afecta a cómo se interpreta un literal entero. El resultado de la expansión aritmética todavía se expresa en base diez, independientemente).

Para las bases 11 a 36, ​​las letras inglesas A a Z se usan para los valores de dígitos 10 a 35. Esto no distingue entre mayúsculas y minúsculas. Sin embargo, para las bases 37 a 64, son las letras inglesas en minúsculas las que se usan para los valores de dígitos 10 a 35, mientras que las letras mayúsculas se usan para los valores de dígitos 36 a 61, el signo at @ se usa para las cifras el valor 62, y el subrayado _ se usa para el valor de dígitos 63. Por ejemplo, 64 # @ A3 indica 256259 ( 62 × 64 2 + 36 × 64 + 3 ).

También hay dos notaciones especiales: el prefijo de un literal con 0 indica la base ocho (octal), y el prefijo de 0x o 0X indica la base dieciséis (hexadecimal). Por ejemplo, 030 es equivalente a 8 # 30 , y 0x6F es equivalente a 16 # 6F .

Variables enteras 

Una variable se puede declarar como una variable entera, es decir, su «atributo entero» se puede «establecer», usando esta sintaxis:

declare -i n
Después de ejecutar el comando anterior, cualquier asignación subsiguiente a n hará que el lado derecho se interprete automáticamente como una expresión aritmética. Por ejemplo, esto:
declare -i n
n='2 + 3 > 4'
 Es más o menos equivalente a esto:
 n  =  $ ((  2  +  3 > 4  ))

excepto que la primera versión declare -incontinuará afectando las tareas posteriores también.

En la primera versión, note el uso de comillas en el lado derecho de la tarea. Si hubiéramos escrito n = 2 + 3> 4 , habría significado «ejecutar el comando + con el argumento 3 , pasando la variable de entorno n configurada a 2 y redirigiendo la salida estándar al archivo 4 «; es decir, establecer el atributo entero de una variable no afecta el análisis global de las declaraciones de asignación, sino que simplemente controla la interpretación del valor que finalmente se asigna a la variable.

Podemos «anular» el atributo entero de una variable, desactivando este comportamiento, usando el comando opuesto:


declare +i n

El comando declare incorporado también tiene otros usos: hay algunos otros atributos que una variable puede tener, y declare tiene algunas otras características además de activar y desactivar los atributos. Además, algunas de sus propiedades destacan:

  • Al igual que con local y export , el argumento puede ser una asignación de variable; por ejemplo, establece el atributo entero de $ n y lo establece en 5 .declare -i n = 2 +3
  • Al igual que con local y export , se pueden especificar múltiples variables (y / o asignaciones) a la vez; por ejemplo, declare -i n=2+3 establece tanto el atributo entero de $ m como el de $ n .
  • Cuando se usa dentro de una función, declare implícitamente localiza la variable (a menos que la variable ya sea local), lo que también tiene el efecto de desarmarla localmente (a menos que se use la sintaxis de asignación).

Aritmética no entera 

Como se mencionó anteriormente, Bash shell arithmetic solo admite aritmética de enteros. Sin embargo, los programas externos a menudo se pueden usar para obtener una funcionalidad similar para valores no enteros.

En particular, la utilidad de Unix común bc se usa a menudo para esto. El siguiente comando:

 echo  "  $ (  echo  '3.4 + 2.2'  | bc )  "

impresiones 5.6 .

No hace falta decir que, dado que bc no está tan estrechamente integrado con Bash como lo es la aritmética de shell, no es tan conveniente; por ejemplo, algo como esto:

# imprimir las potencias de dos, de 1 a 512: 
for (( i = 1 ; i < 1000 ; i *= 2 )) ; do
  echo $i
done

sería, para soportar no enteros, convertirse en algo como esto:

# imprimir los poderes de la mitad, de 1 a 1/512: 
i=1
while [ $( echo "$i > 0.001" | bc ) = 1 ] ; do
  echo $i
  i=$( echo "scale = scale($i) + 1 ; $i / 2" | bc )
done

Parte de esto se debe a que ya no podemos usar un aritmética for-loop; parte de esto se debe a que hacer referencia a las variables y asignarlas a las variables es más complicado ahora (ya que bc no es consciente de las variables de la shell, solo de las suyas, no relacionadas); y parte de ello se debe a que bc se comunica con el shell solo a través de entrada y salida.

!Y  esto  es todo por hoy!Pero no se preocupe en proximos post trataremos otrso temas como entrada/salida, funcionaes complejas y mucho mas

Mas informacion en  https://en.wikibooks.org/wiki/Bash_Shell_Scripting