./jim
-----
Commando principal de Jaime para classes de Linux

Usage: jim [options] function
Function list:
--------------
linux01
System: Archivo: De donde vengo, donde estoy, a donde voy

linux02
-- Tarea: mkdir, touch, cp, mv, rm

linux03
-- Tarea: df, du y misc

linux11
Syntax: Tubo: Redirecion, Cita y Expancion

linux12
-- Tarea: wc, seq, sed, ask, bash

linux21
System: Red: Usarios y Machinas

linux22
-- Tarea: route, traceroute, dig, useradd

linux31
Syntax: Subshell: Jobs, Signal, Command expansion

linux32
-- Tarea: man, apropos, pstree, /dev/random

linux41
System: Explorar: Process, Device: pstree, /dev/zero

linux42
-- Tarea: dd, filefrag, fork, exec

linux43
-- Examen: medio cyclo

linux51
Syntax: Monolinea: Recreo

linux52
-- Tarea: Monolinea: Ciclo de vida del desarrollo de programas

linux61
System: Heramientas: Docker y Git

linux62
-- Tarea: Heramientas: wget, curl, chroot, docker, git

linux71
Syntax: Language: Funcion, Rama, Ciclo y Regex

linux72
-- Tarea: Language, flujo de control y Regex

linux81
System: Servicio y Servidor:

linux82
-- Tarea: wget, cron, cgi, jenkins

linux91
Sintaxis: Lenguaje: Ecosistema: Niveles de idioma

linux92
-- Tarea: Zoo de lenguajes

linux93
-- Examen: fin de cyclo

misc
Misceláneo: Recursos para las clases

sync
Sinconizacion: de la clase

Option list:
------------
--doc
Print documentation (longer than help)

--help
Print this message

--print
Only print command instead of executing




linux01
-------
System: Archivo: De donde vengo, donde estoy, a donde voy


================+
|  File System  |
================+

P01: Donde estoy (PWD)?
  > pwd
  'Present Working directory': te dice en que directorio estas, los commandos se ejecutaran en este directorio

P02: Donde voy (CD)?
  > cd Class
  'Change directory': te mueve a un otro directorio (como un doble click en una carpeta). Aqui el directorio Class no existe, entonces te da un error.
  Nota que cd sin argumento te mueve a tu casa (donde estas ahora)

P03: Crear directorios (MKDIR)
  > mkdir Class
  'MaKe DIRectory': Crea una carpeta llamada Class en la carpeta donde estas ahora.
  More, para crear directorios imbricados, puedes usar la opcion -p. Como en {cyellow}mkdir Class/Dir1/Dir2/Dir3

P04: Listear los archivos de un directorio (LS)

  Ahora si puedes ir en la carpeta Test
  > cd Test
  > pwd
  Estas bien en /home/tourneboeuf/Test?

  Vamos a crear distintos archivos (confia en mi)
  > for i in {1..10}; do touch file_$i; done
  > mkdir Dir1
  > for i in {1..10}; do touch Dir1/file_in_dir_$i; done

  Y Miramos lo que hay en la carpeta del pwd
  > ls

P05: Crear archivos (vacios) (Touch)
  > touch file_con_nombre_cualquiera.txt
  'Touch' Toca un archivo, dandole vida (el soplo de dios)
  Ahora juega, quiero que tengas 20 archivos en la carpeta corriente

P06: Remover (RM)
  > rm file_con_nombre_cualquiera.txt
  'ReMove' Es un commando my peligroso, usalo con cuidado o mejor, no lo uses, mejor 'Mover a la basura' que remover, lo que nos lleva al ejercicio siguiente:

P07: Mover (MV)
  > touch file_new.txt  # Crea archivo
  > mkdir ~/Trash  # Crea basura en tu casa: ~ es un alias para tu casa
  > mv file_new.txt ~/Trash/  # Mueve el archivo a la basura
  'Move' mueve un archivo o una carpeta desde una carpeta a una otra

P08: Historia (HISTORY)
  > history
  'History' te muestra todo los commandos que hiciste haste ahora, las teclas arriba y abajo tambien te permiten navegarlas

P09: Limpia pantalla (CLEAR)
  > clear
  'Clear' permite limpiar tu terminal


The end
  Muy bien, la clase de hoy estaba sobre:
  pwd, cd, mkdir, ls, mv, rm, history, clear

  Maniana vamos a ver:
  echo, cat, man, apropos, head, tail, less

  A retener: son muchos pequenios commandos que hacen solo una cosa pero la hacen bien. Esta ultima assercion es la filosofia de Linux
  



linux02
-------
-- Tarea: mkdir, touch, cp, mv, rm


========================+
|  File System Homework |
========================+


Homework 1: Moving FIle and directory and yourself

P01: Create a simple text file with the following console commands:
  > touch simple_file.txt
  > echo "Ejemplo de archivo de texto
para el curso de Linux" > simple_file.txt

P02: Create two directories with the Linux command mkdir
  > mkdir txt
  > mkdir log

P03: Copy simple_file.txt into txt directory
  > cp simple_file.txt txt

P04: Rename simple_file.txt to simple_file.log with the Linux command mv
  > mv simple_file.txt simple_file.log

P05: Move simple_file.log to the log directory
  > mv simple_file.log log

P06: List files of the directories txt and log with the command ls
  > ls txt log

P07: Create a new directory named local
  > mkdir local

P08: Move files of directories txt and log into local directory
  > mv txt/simple_file.txt local
  > mv log/simple_file.log local

P09: Delete directories txt and log
  > rm -rf txt
  > rm -rf log

P10: List the current directory with command ls
  > ls

P11: List directory local
  > ls local


Homework 2: basic edit files and running scripts

P11: Creating first script in bash
    nano primer_script.sh
    Add the following lines to the file.

    #!/bin/bash

    echo 'Hola Mundo'

    Save the file (pressing control-s to save and control-x to exit)
    Ctrl-s Ctrl-x

    Run the script (comment about the output of the script execution)
    bash primer_script.sh
  



linux03
-------
-- Tarea: df, du y misc


+==================+
|  File System Bis |
+==================+

P01: CoPy (CP)
  > cd ~/Test
  > touch test1.txt
  > cp test1.txt test_new.txt

P01: Disk Format (DF)
  > df
  > df -m
  Cual es la diferencia?
  > man df
  Presiona 'q' (como Quit) para salir

P02: Disk Usage (DU)
  > du .
  > du ~

P03: CHange MODe (CHMOD)
  > echo 'echo Message from the file' > script.sh
  > ls -l
  > ./script.sh
  > chmod +x ./script.sh
  'x' como eXecute, que cambio este commando?

P04: CHange OWNer (CHOWN)
  > chown root:root ./script.sh
  > ls -l
  > ./script.sh
  > chown jim:jim ./script.sh
  jim:jim significa usario jim y grupo jim. Que es la diferencia entre usario y grupo?

P05: Your Name (UNAME)
  > uname -a

P06: Host Name (HOSNAME)
  > hostname
  > hostname -I

P07: Ping (PING)
  > ping www.google.com
  Tienes acceso a internet?
  Que puerto usa el ping? El HTTP? El HTTPS? Porque diferentes puertos?


End
  Felicitacion, para ir mas lejos:
  - Description of an inode
  - mount, fdisk, mkfs, lsblk




linux11
-------
Syntax: Tubo: Redirecion, Cita y Expancion


+===============+
|  Redirections |
+===============+

a/ Acuerdate: En Linux, todo es archivo!
b/ En Linux existe lo que se llama descriptores de archivos o (file descriptor o simplemente fd para los intimos van de 0 a 9). Acuerdate que empezamos a contar de 0 como para las cuadras
c/ Los 3 primeros son importantes:
  - fd 0: StdIn: la entrada estandar de un commando
  - fd 1: StdOut: la salida estandar de un commando
  - fd 2: StdErr: el error estandar de un commando. Suele ser usado para los humanos. No cunfundir con el codigo de retorno
d/ Cada commando retorna un numero entre 0 y 255 (en un byte no mas como en 1970). Si este numero es 0 es que el commando ha sido existoso, sino es que fallo. Y con eso ya empezamos a programmar: Si fallo: haga eso, sino: hago eso lo que se llama ramas (branches). Y si agregamos ciclos (loop) tenemos todo de un idioma Turing complete. Lo que es BaSh

Gracias por leer,
Vamos!


P01: Escribe a la salida estandar (ECHO)
  > echo un texto cualquiera
  > echo 'un texto cualquiera'
  > echo "un texto cualquiera"

P02: Interpolacion de variables ($)
  La diferencia entre la simple cita ' y la doble " es que el la doble, hay interpolacion de variable.
  Nota que no hay espacio alrededor del operador =
  Nota que BaSh es muy sencible a los espacios: separan el commando de los argumentos, los argumentos entre si, los commandos entre si, los 'token' (como >, |, <, o &)
  Ya que tengo espacio en el contenido de la variable, tengo que ponerle unas citas
  > var="contenido de la variable"
  > echo Eso es mi $var
  > echo "Eso es mi $var"
  > echo 'Pero vez, eso no es mi $var'

  El $var no se expende con el valor del variable con los las citas simple single quote. La comillas simple dan al comando el texto como es.
  Que pasa si no pongo en commilla?

  > var=contenido de la variable

  Porque?

P03: Redirecion de salida (>)
  Escribir en la terminal esta bien, pero es el arenero, los grandes deben escribir en otras cosas: RAN, Archivos, Puertos, Pantalla, Otros terminales, y sabes que todos esos son archivos.
  > content="Line 1
Line 2
Line 3
Line 4
Line 5
"
  > echo $content > new_file.txt
  Pero cuidado, eso bora el contenido previo de file_new.txt.

  Para borar un arvhivo, hay un modismo que usa el commando llamado Nop para No OPeracion, ese es ":"
  > : > new_file.txt
  Se borro !

P04: Redirecion de salida en agragacion (>>)
  Para agregar, usa el dobe >>
  > : >> new_file.txt
  > echo $content >> new_file.txt
  > echo $content >> new_file.txt
  > cat new_file.txt

P05: Redirecion entrada (<)
  > cat < new_file.txt
  > sed 's/Line/Otra Wea/' < new_file.txt

  La uso muy poco porque en general los commandos acceptan nombre de archivo como argumentos (por eso no deben tener espacios).
  En general, es commun remplacar una redirection de salida con un cat en un tubo ...

P06: Tubo (|)
  El tubo redirige la salida de un comando en la entrada de uno
  >  -  # Permite escribir la entrada en la salida (basicamente no hace nada, como ":")
  > tee file_in_pipe.txt  # Duplica su entrada en el archivo file_in_pipe.txt y en su salida estandar

  > jim class021 top_tag  # Muestra los primeros tag de StackOverflow
  > jim class021 top_tag | grep -v '^ *#'
  > jim class021 top_tag | grep -v '^ *#' | grep -v '^ *$'
  > jim class021 top_tag | grep -v '^ *#' | grep -v '^ *$' | sort -n -k 2
  > jim class021 top_tag | grep -v '^ *#' | grep -v '^ *$' | sort -n -k 2 | head -n 20
  > jim class021 top_tag | grep -v '^ *#' | grep -v '^ *$' | sort -n -k 2 | head -n 20 > language_mas_populares.txt


P07: StdErr A ver juntos


End

Felicaitacion de nuevo suegrito!
Los tubos son geniales, te voy a dar trabajo en casa.
Tu mejor amigo en man






linux12
-------
-- Tarea: wc, seq, sed, ask, bash


+=========================+
|  Redirections: Homework |
+=========================+


P01: Guardar las clases en un texto
  Habia que remover los colores
  > sed 's/\x1b\[[0-9;]*m//g'

  Hay una opcion en el commando jim que permite correr toda la doc de los escript que resulta ser las clases:
  > jim --doc

  La solucion es entonces
  > jim --doc | sed 's/\x1b\[[0-9;]*m//g' > clases.txt


P02: Muestra todo los commandos en tu historia que tenian el commando "sed"
  Puedes Agrarar (Grab en ingles -> Grep) las lineas que contienen "sed" con
  > grep sed

  Y ver tu historia con
  > history

  Lo demas es el tubo


P03: Cuantos procesos BaSh coren en tu maquina (virtual)
  Listeas los commandos que corren con
  > ps -ef
  Ps para ProcesS, E para Every y F para Full Format

  Agara solo los BaSh con
  > grep bash
  Pero mira que te vew a ti mismo, mira el ultimo processo no es un bash, es el mismo "commando tubo" (pipeline) que estas corriendo que se "agaro" (grep) a si mismo, que absurdo!

  Cuentas las lineas con
  > wc -l
  Word Count -Line

  Y finalmente, ya que estamos aqui, substraes uno con
  > echo $(( $(cat -) - 1 ))
  Que es el echo de la evaluacion arithmetica $(()) del input estandar $(cat -) menos uno.
  Nota que la expresion $(cat -) es una interpolacion de commando que no hemos visto, pero que es muy facil, solo se interpola con el StdOut del commando adentro

  Lo total te da
  > ps -ef | grep bash | wc -l | echo $(( $(cat -)-1 ))
  Lo que es largo y no lo quieres escribir 2 veces.
    1. Lo puedes bucar en tu historia
    2. Lo puede poner en una function (y despues en un archivo como ese mismo que lees)

  > count_bash(){ ps -ef | grep bash | wc -l | echo "Hay $(( $(cat -)-1 )) procesos BaSh corriendo ahora"; }
  Para definir la funcion, y despues
  > count_bash
  Para usarla

  Lo lograste? BaKaN! Tu primera funcion en BaSh. Vez que el Shell es un idioma real, aunque sea debil para cosas (arithmetica, velocidad, seguridad ...) es el mejor del mundo para los tubos.
  Y corre en todas maquinas, tambien tu Window, tambien mi Android. Pero eso es para esta noche.


P04: Cuantos Commandos unicos has corrido
  Nota: utilisa los commandos:
  > uniq
  > wc -l


P05: Cuantos numeros primos entre 1 y 1000
  Regalo: Aqui te escribo una funcion que filtra los numeros primos usando el commando factor (que quizas tienes que instalar

  > is_prime(){ while read line; do factor $line | grep -qE '^(.*): \1$' && echo $line; done; }
  Que se lee mejor asi (es la misma, tienes que copiarla solo 1 vez):
  > is_prime(){
    while read line; do  # Para cada linea del StdIn
       factor $line | grep -qE '^(.*): \1$' && echo $line;  # Si el comando factor no tiene mas que un numero en salida, echo el numero
    done
  }

  Para imprimir la sequencia de 1000 numeros, nada mas facil:
  > seq 1000

  Y como de costumbre, cuenta las lineas.

  Encontraste 168? Felicitacion!

P06: Un caso Real: Pipe To BaSh
  Muchos ejemplos de informatica son de arithmetica, aunque que quasi jamas se usa (es mas facil para el profe generar numeros que textos).
  Ahora vamos a ver un caso muy muy comun de los tubos, que llamos el tubo hacia BaSh
  Acuerdate de la funcion de la clase: Los 20 tags de informatica los mas de moda.

  Lo imbricamos en una funcion:
  > echo_tag(){ jim class021 top_tag | grep -v '^ *#' | grep -v '^ *$' | sort -n -k 2 | head -n 20 ; }

  Corre la funcion:
  > echo_tag

  Para cada linea, queremos crear un archivo, que tiene como prefijo su rango, como nombre, su tag y como contenido sus puntos. Por ejemplo el archivo "1_javascript" con contenido "2097175" y el archivo "2_java" con contenido "1717945".
  Vamos a hacer los comandos "echo 2097175 > 1_javascript" y "echo 1717945 > 2_java" y ...
  Pero no los vamos a copiar a mano! Vamos a generar estos comandos, imprimirlos en el StdOut y hacer un tubo hasta BaSh (en interpretador0 que entonces va a ejecutar estos commandos.

  Pequenia prueba:
  > echo 'echo hola hablo demasiado > test_file.txt'
  > echo 'echo hola hablo demasiado > test_file.txt' | bash
  > cat test_file.txt

  Grande prueba (en arenero es decir la terminal como StdOut, asi no rompes nada):
  > echo_tag | awk '{print "echo " $3 " > "  $2 "_" $1 ".txt"}'
  El comando awk, es expreto en cambiar columnas, aqui imprime en orden echo, la columna 3, el simbolo >, la columna 2 ... Como siempre, cuida los espacios

  Grande test:
  Copia pega la primera linea, ejecutala, ve si el archivo se creo, copia pega otra linea, se creo ? Entonces esta todo bien. Ahora si pudes dispara el mega commando que tendra efectos de bordos grandes (generar 20 archivos que es su objectivo)
  > echo_tag | awk '{print "echo " $3 " > "  $2 "_" $1 ".txt"}' | bash

  Todo bien! Ouf no rompimos nada (esta vez), mientras no usas el commando prohibido, y trabajas en un direcotrio de Test, uchas cosas deberian ser reversibles.

End
  Felicitacion, Los tubos (pipeline) deben mucho a los filtros.
  Esta noche vermos los usarios y las machinas (alias la red).
  Si quieres adelantarte: su -, who, w, whoami, ip or ifconfig, dig, traceroute, route
  Y el comando de los hacker: nmap si prepare bien la clase.
  



linux21
-------
System: Red: Usarios y Machinas


+=============================+
|  User and Machines: Network |
+=============================+

Que es un usario, que es una machina
Son ambos numeros segun la machina y nombre segun el humano.
Una machina, un programa, un humano o un conjuto de esos puede ser usario.
La machina tiene un puerto abirto y puede ejecutar codigo, es mano de obra disponible, el usario es un jefe latente.


+================================+
|  Parte 1: Defense your machine |
+================================+

P01: Quien soy (whoami)
  > whoami
  > echo $USER


P02: Quien conoce esta machine (/etc/passwd)
  > cat /etc/passwd
  > cat /etc/passwd | awk -F: '{print $1}' | sort
  > cat /etc/passwd | grep "^$USER\|^root:"


P03: Quien esta en esta machina (w)
  > who
  > w  # mas informacion


P04: Cual es esta machina (hostname)
  > uname -a

  Nota que desde aqui, empezamos a considerar la maquina relativa a su entorno, asi que eso puede cambiar si la machina cambia de lugar.
  En toda esta clase, nos quedarmos en la red local (de la casa) (192.128.0.1) porque es mas seguro

  > hostname -I
  > ip address
  > ifconfig -a  # ya no se usa


P06: Que puertos estan abiertos aqui (defensa nivel 1)
  > sudo netstat -laputen   # maybe you must run> apt install net-tools

  Pensar NETwork STATistic la pute (puta en frances), son muchas opciones para tener muchas informaciones

  > sudo ss -tlunp  # Lo mismo despues de 2018

  Pero como todo es arvhivo

  > sudo lsof -nP -i
  LiSt Open File


P07: Que pasa en wikipedia.com (ataque nivel 1)
  > ping wikipedia.com
  > whois 208.80.154.232  # Donde 208.80.154.232 es el IP que se obtiene con ping


P08: Descargar desde wikipedia.com usando falso archivos
  Eso ya se esta poniendo complicado a mano.
  Un ejemplo pre 2000
  > exec 3<>/dev/tcp/www.het.brown.edu/80;  # "Solo" pido enchufar el "archivo aparato" al file descriptor 3
  > echo -e "GET /guide/UNIX-password-security.txt\r\n" >&3;  # Mando un GET request escribiendo
  > cat <&3  # Ahora leo el retorno leyendo


P09: Descargar desde wikipedia.com (wget)
  Ahora con HTTPS y para descargar sitios enteros ... mejor usar una heramienta
  > wget https://en.wikipedia.org/wiki/Unix_philosophy
  Web GET. Que obviamento debes instalar con
  > sudo apt install wget



+================================+
|  Parte 2: Attack my machine    |
+================================+

P20: Primordial
  Agrege el usario jim en la machina 9 con:
  > useradd --home /home/jim jim  # agrega el usario
  > passwd jim  # Da la clave
  > usermod --shell /bin/bash jim  # Dice que su shell es Bash (que es de 1990 <= no se porque era /bin/sh que es de los 1970)


P21: Ok vamos (SSH)
  Puedes ver la lista de las machinas con jim class031 system_map
  > ssh 192.168.0.9
  Bienvenido en mi maquina personal Jim

  > whoami; hostname  # aprecia que ";" separa los commandos
  > espeak "Hi, I am user $USER and in machine $HOSTNAME"


P22: Rapatriar (SCP)
  Para tenerlo en tu machina
  > scp jim@192.168.0.9:Test/Jim/secret.md secret_local.md


End:
  Buen trabajo!
  



linux22
-------
-- Tarea: route, traceroute, dig, useradd


+==============================+
|  User and Machines: Homework |
+==============================+

P01: Un poco de calle (Route)
  Seguir el ejercicio de 10 commandos ahi:
  https://www.geeksforgeeks.org/route-command-in-linux-with-examples/
  Pero primero, guadar la table de ruteo:
  > route > route_save.txt


P02: Sal de tu casa (IP externa)
  Has visto hostname -I, ip adrress, or (ifconfig en linux or ipconfig en window).
  Pero eso te da solo la IP interna.
  Para pedir la IP externa, pidela a un sitio simpatico (aqui ipinfo)
  curl puede hacer cualquier commando TCP y dar la vuelta en la terminal. Es mas primitivo que wget. Se usa mucho para hacer un simple GET or POST

  curl https://ipinfo.io/ip
  Te deberia dar, como yo 201.241.56.254

  Aparte sobre lo Local Vs Externo:
  Entonces, del exterior, cual es la differencia entre tu y yo: si los otros (los sitios web) nos ven con la misma IP, como pueden elejir a quien mandan las paginas (Pensar 10 sec).
  Obivamente el puerto! Si yo pido una pagina wikipedia.org desde el puerto 42666 y tu una pagina uber.cl desde el puerto 12345, wikipedia responde al puerto 42666 del router que esta inteligentemente ligado al puerto 42666 de MI machina y advina, uber.cl respondera al puerto 12345 del router que esta iteligentemente ligado al puerto 12345 de TU machina.
  Asi YO no veo TU uber.cl y TU no vez MI wikipedia.
  Fin del aparte.

  Quien es dueno de tu modem (alias router):
  > whois 201.241.56.254

  En que lugar:
  curl https://ipvigilante.com/201.241.56.254
  (En mi caso, el sitio cayo, asi que no se en que lugar estoy)


P03: Seguir una solicitud (Traceroute)
  > traceroute www.normandie-tourisme.fr
  La primera linea indica el IP del objectivo, despues, cada line indica el router siguiente en el camino: la pimera indica el router de tu casa y la ultima, el router de la casa del objectivo.

  Son muchos IP, no resulto, prefiero nombres de paices, ciudades: Admira este commando
  curl https://ipvigilante.com/213.242.127.158

  Eso huele bastante a un Pipe to BaSh

  a/ Primero guadamos el StdOutput del commando lento
  > traceroute -n www.normandie-tourisme.fr > trace.txt

  b/ Saca la primera linea: sed = Stream EDitor, -n = silent = no imprimir cada linea, 2,$ = para la lineas entre 2 y ultima (incluida), p = print
  > cat trace.txt | sed -n '2,$ p'

  c/ Saca las lineas sin IP: grep = agara, -v = invert = todo lo que no tiene, dos espacios y una estrella
  > cat trace.txt | sed -n '2,$ p' | grep -v '  \*'

  d/ Jugamos con las columnas. Nota que 2> /dev/null significa: redirige el descirptor de archivos 2 (Standard Error) al dispositivo nulo, el agujero negro /dev/null, para no ver los errores de curl
  > cat trace.txt | sed -n '2,$ p' | grep -v '  \*' | awk '{print "echo " $1 " $(curl ipvigilante.com/" $2 " 2> /dev/null)" }'

  e/ Ahora si, toma las precausiones adecuadas ( intenta con una o dos lines y Pipe to BaSh
  > cat trace.txt | sed -n '2,$ p' | grep -v '  \*' | awk '{print "echo " $1 " $(curl ipvigilante.com/" $2 " 2> /dev/null)" }' | bash


P04: Un poco mas pro que ping (dig)
  Te mostre un ping wikipedia.org que uso para saber su IP, tomar, del nombre de dominio el IP se llama DNS lookup (para Domain Name Service). El commando asociado es dig.
  Perdoname, ping siempre ha sido bastante para mi. Te lo digo porque aparece en entrevista de trabajo, es mas pro, mas facil poner en un escript, te puede dar los distintos IP ... mas informaciones ahi: https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/
  Como simpre, muy facil de usar:
  > dig wikipedia.org


P05: Mas usarios
  Para esta tarea, agrega 1 o 2 usarios a tu machina (voy a verificar) jim2 y jim3 por ejemplo.
  Agrega sudo antes de todo estos commandos.

  > useradd -m -s /bin/bash jim2
  Crea el usario jim2
    Opcion -m (--create-home) option to create the user home directory as /home/username:
    Opcion -s (--shell) option para especificar el Shell por defecto del usario (sin no lo especificas, usa /bin/sh de 1970 y no bash de 1990-2000, lo que es termible, no hay color ni complecion y hay bug)

  > passwd jim2
  Dale la clave jim2

  > useradd -m -s /bin/bash jim3
  > useradd -m -s /bin/bash jim4
  > cat /etc/passwd
  Se agregaron los usarios? Bakan, bastante jugado sacalos Ya!

  > userdel jim3
  > userdel jim4
  > cat /etc/passwd
  Ya no estan? Que bueno, conserva jim2

  Y connectate (login) como jim2 a tu propia machina
  > su - jim2  # Dale la clave jim2
  > whoami  # jim2? Bakan
  > exit
  > whoami
  > exit
  Ah ya saliste de tu ultimo subshell, en todo caso, se acabo el ejercicio de hoy.


End:
  Hemos visto:
    En clase: whoami ($USER), hostname ($HOSTNAME), w, ip, y sobre todo ssh
    En casa: route, traceroute, curl (un poco), dig, useradd, passwd, userdel, (existe usermod pra modificar), la redirecion "2> /dev/null" un poco que muestra que una redirecion puede ser de otro descriptor de archivo que el StdOut (aqui el StdErr) y que nos muestra un uso del dispositivo nulo (alias el agujero negro)

  Maniana:
    jobs, fg, bg, pstree, kill, Crl-c, Ctrl-Z, /dev/random, glob, command expansion
    y, si hay tiempo, usar un editor de texto (vim, nano, emacs, GUI text editor), y hacer codigo: ramas (if), ciclos (for) y funciones (function)

    Felicitacion! Hemos hecho muchisimo en 1 semana. En 2 clases mas, empezaremos a ver heramientas mas pesadas para synchronisar (git), descargar (wget), o editar (vim) pero nunca, no Nunca, dejaremos lso tubs y sus poderes (ex: cat file.txt | grep "text to search")
  



linux31
-------
Syntax: Subshell: Jobs, Signal, Command expansion


+=================+
|  SubShell: Jobs |
+=================+

+======================+
| Parte 1: Expanciones |
+======================+
  Antes de ejecutar cualquier linea, BaSh hace unas expanciones.
  Puedes leer (mucho) mas sobre eso en man bash seccion "EXPANSION".


P01: Expancion de casa: ~
  Ya hemos visto como la tilde "~" se expande:
  > echo ~
  > echo ~jim2
  Si! Como el camino a tu casa, 1 character, para que sea facil encontrar tu casa!


P02: Expancion de camino: *
  > echo *  # Muestra todo los caminos
  > echo *.txt  # Muestra todo los caminos acabando en ".txt"
  > echo file*  # Muestra todo los caminos empezando con "file"
  > echo /usr/*/share  # Muestra todo los caminso empezando en "/usr" con "/share"
  Est symbolo "*" Se llama el glob porque engloba "cualquier wea tipo "file*" significa file seguido por "cualquier wea".
  Este tipo de especificacion de nombre (aqui de camino) es una exprecion regular. Y es muy potente!


P03: Expancion de llave, como el "o": {}
  No es muy muy util, solo achica un poco los commandos
  > echo estoy-{feliz,triste,boracho}
  > echo {estoy,soy}-{feliz,triste,boracho}
  Es como el "o" estoy feliz o triste o contento. Puede multiplicr rapidamente los argumentos.


P04: Expancion arithmetica: $(())
  > echo $((2 + 2))


P05: Expancion de variable: $
  > echo $USER
  > toto="adentro"; echo $toto


P06: Substitucion de commando: $()
  Esa es muy util!
  Remplaza el $(commando argumento) con el StdOut del command corrido
  > echo $(ls)
  > echo "$(ls)"
  > ls -l $(which cp)
  > file $(ls /usr/bin/* | grep bin/zip)

  Nota que todo las interpolaciones con $ se ejecutan en "" pero no en ''

  SubShell: Cuando ejecutas un commando en una substitucion de commando, la ejecutas en un subshell.
  Es importante entender lo que se puede pasar de un shell a otro (en tarea)
  echo $BASH_SUBSHELL
  echo $(echo $BASH_SUBSHELL)
  echo $(echo $(echo $BASH_SUBSHELL))



+=============================+
| Parte 2: Senales y Trabajos |
+=============================+

Las senales es la version la mas primitiva (en 1970) de las communicaciones entre processos.
Desde ya, han sido muy, muy criticados. Pero no solo existen, tambien Windows los ha implementado. Porque?
Porque, en 50 anios, en realidad, nadie logra hacer mejor.
Nota que la version mas desarollada de communicacion entre procesos son los "sockets" y funcionan con IP (Internet Protocol). lo que corresponde en linux en escribir en un archivo. Tambien existen los tubos, tubos con nombre, la memoria compartida (tambien escriir y leer "archivos")
Mas informaciones en man 7 signal.

Los trabajos son todo los procesos que ha ejecutado un shell, cada linea si corre un commando o un tubo (pipeline) es un trabajo.


P10: Trabajos de fondo
  Necesitamos un function de trabajo que lee el StdIn pero no escribe en el StdOut.
  Vamos a usar nano y vim <= son editores de texto.
  > nano file1
  Ctrl-X para salir
  > vim file1
  ":q" para salir, si el archivo se modifico: ":q!"


P11: Segnales: Ctrl-z, Ctrl-c
  > nano Jim1
  Apreta Ctrl-z
  Mandaste al ultimo trabajo (nano Jim1) la senal: 19 - SIGSTOP - Pause the process / free command line, ctrl-Z (1st)
  > nano Jim2
  Apreta Ctrl-c
  Mandaste al utltimo trabajo (nano Jim2) la senal: 2 - SIGINT - interupt process stream, ctrl-C 


P12: Senales: Fondo (bg)
  > nano Jim3 &  # Nota que "&" corre directamente el trabajo en background, es lo mismo que lo siguiente
  > nano Jim4  # Press Ctrl-z
  > bg  # Press Ctrl-z


P13: Segnales: Primer plano (fg)
  > nano Jim5 &
  > fg


P14: Jobs and kill
  Hay 2 seniales utiles:
    15 - SIGTERM - terminate whenever/soft kill, typically sends SIGHUP as well? 
    9 - SIGKILL - terminate immediately/hard kill, use when 15 doesn't work or when something disasterous might happen if process is allowed to cont., kill -9 

  Listea los senales:
  > trap -l

  Ahora a matar los trabajos
  > jobs  # Listea los trabajos
  > kill -15 %2  # Manda la senial 15 (TERMINATE) al trabajo numero 2
  Ahora TERMINA o MATA todo tus trabajos


P15: Otro Shell
  > bash  # Te hace entrar en un otro shell
  > exit  # Te hace salir de ese
  Que pasa de un shell a otro?
  Hablar de herencia


End:
  Acabaste la clase 4. Felicitacion!

  Has aprendido: Las expanciones de Bash con ~, *, {}, $, $(()), $()
  
  Manana veremos: Los processos y los dispositivos

  De nuevo, buen trabajo,
  Buenas noches.
  



linux32
-------
-- Tarea: man, apropos, pstree, /dev/random


+===============+
|  Jobs: Tareas |
+===============+

Hay pocos ejercicios pero son largo => piano piano lontano


P01: Listea y describe los commandos cononcidos
  Me preguntaste: "Hay un sitio para listas de commandos ?"
  Y te respondi: "Mejor vealo en TU sistema y mantenga tus notas tu mismo."

  Para resumir los commandos de esta clase, corre este commando:
  > jim --doc | grep -ao '> \(sudo \)\?\w\+' | sed 's/sudo //' | cut -c 3- | sort -u | awk '{print "apropos -l \"^" $1 "$\""}' | bash 2>&1 | grep -v "nothing appropriate"
  Puedes redirecionar el output de este en un archivo para leerlo mas tranquilo

  --> Aparte
  A ver lo que hace <= es un interesante ejemplo real.
  No copies estos commandos, es solo una descripcion:
  > jim --doc  # Ese es un commando que el yo hice, que escribe todo el el StdOut
  > grep -ao '> \(sudo \)\?\w\+'  # Agara: -a = considera el input como texto, -o = escribe solo lo que agaro y lo las lineas enteras como el defecto, un character ">", despues "sudo " o no "\?", despues characters de palabra "\w", 1 o mas "\+", ese ultimo argumento es una Exprecion Regular
  > sed 's/sudo //'  # Remplaza "sudo " (sudo y espacio) por nada (en cada linea)
  > cut -c 3-  # Corta (Cut) los 3 ("3") primeros caracteres ("c")
  > sort -u  # Ordena lexicographicamente de forma unica: lo mismo que sort | uniq pero mas rapido (porque corre un processo y no dos)
  > awk '{print "apropos -l \"^" $1 "$\""}'  # Reordona un poco la impression, poniendo apropos antes que es un commando como man: ver (> apropos hostname)
  > bash 2>&1  # Pipe to BaSh para ejecutar apropos. Y redireciona la Salida 2 (StdErr) a la 1 (StdOut) porque apropos, aparetemente escribe en el StdErr pero los tubos solo redirectionan el StdOut
  > grep -v "nothing appropriate"  # Agara todas las lineas excepto las que contienen "nothing appropriate", porque son lineas donde apropos no encontro nada, porque no eran commandos sino nombre de archivos
  <-- Fin del aparte

  Elegante? O super feo?
  Ambos! Pero ha sido facil de escribir (paso a paso), y hace automagicamente las tareas de extracion y reporte.


P02: Los subshells crean otro procesos
  Escribe un programa que genera un subshell que trabaja
  > echo '(while true; do echo "Subshell running . . ."; sleep 0.3; done; )' > subshell.sh
  Ejecutalo (Mejor dicho interpretalo con Bash) en fondo, pero redireciona su StdOut al agujero negro (sino te llena la pantalla y es molestoso).
  > bash subshell.sh > /dev/null &
  Observa que se genero dos processos.
  > ps -aux | grep subshell.sh
  El proceso creo un hijo al entrar en un subshell

  Y si entras en un subshell desde un subshell (imbricacion):
  > echo '( :; (while true; do echo "Subshell running . . ."; sleep 0.3; done; ) )' > subshell2.sh
  > bash subshell2.sh > /dev/null &
  > ps -aux | grep subshell2.sh
  Ahora son 3 processos

  Con el primer trabajo todavia corriendo en fondo, son 5 processos
  > ps -aux | grep subshell

  Matalos:
  > jobs  # Deberias ver 2 trabajos ya que corriste 2 commandos
  kill %1 %2

  Y no queda ningun processo: Al terminarse, los processos padres mandaron una senal a sus hijos que se acabaron
  > ps -aux | grep subshell


P03: Los subshells clonan toda las variables
  > var=41
  > echo OUTSIDE subshell $var
  > ( ((var++)); echo "INSIDE subshell = $var" )   # Nota la interpolacion arithmetica con (()). No cunfundir con el subshell con simple ()
  > echo OUTSIDE subshell $var

  Pero las variables del subshell no se transiten a su padre.

  Nota que este fenomeno se puede usar como ventaja para tener "variables locales".
  Mas sobre eso en la clase 10: idiomas de programacion.
  Por mientras retiene que todas la varibles que se crean, modifican o destuyen en un subshell, no cambian en su padre porque en realidad no son la mismas variables sino clones.
  Este fenomeno de clonaje es esclusivo al shell, y se demora un poco. Los otros idioma no clonean implicitamente sino que mantienen explicito lo que llaman en enfoque (scope) de una variable y afuera del enfoque, ni se puede ver la variable. Pero eso es otra clase.


P04: Variables $$ y $BASHPID en los subshell
  > clear

  > echo "\$\$ outside of subshell = $$"
echo "\$BASH_SUBSHELL  outside of subshell = $BASH_SUBSHELL"
echo "\$BASHPID outside of subshell = $BASHPID"

  Nota que los {} grupan los commandos pero no crean un subshell: mientras que ejecutar 3 lineas de commandos, es ejecuta una linea de 3 commandos.
  > { echo "\$\$ outside of subshell = $$"
echo "\$BASH_SUBSHELL  outside of subshell = $BASH_SUBSHELL"
echo "\$BASHPID outside of subshell = $BASHPID"; }

  Ahora si entramos en un subshell?
  > ( echo "\$\$ inside of subshell = $$"
echo "\$BASH_SUBSHELL inside of subshell = $BASH_SUBSHELL"
echo "\$BASHPID inside of subshell = $BASHPID" )

  Que variable cambio y como? Anotalo bien, quizas saldra en la prueba!

  Ahora que entiendes los {}, los vamos a ocupar para grupar commandos sin escribirlas todas en la misma linea con ";" o "&" => sera mas facil leerlas pero es lo mismo.


P05: Subshell y asynchronysmo
  > jobs  # Asegurate que no tienes trabajos en fondo antes de seguir. Si hay, matalos con (> kill %12) donde 12 es el numero del trabajo
  > (sleep 1) & (sleep 2) & (sleep 3) & wait

  El commando (> wait) espera que todo los jobs sean terminados antes de terminar. Asi

  Que se puede escribir
  > { (sleep 1) &
(sleep 2) &
(sleep 3) &
wait; }

  Viste que es mas facil leer!


P06: Senal, atrapar Ctrl-C (trap)
  > trap -l  # Recordatorio (no tienes que aprenderlos)
  > trap 'echo "Ctrl-C pressed"' 2  # Define el manipulador (handler) de la senal 2 (SIGINT).

  Presiona Ctrl-C distintas veces para ver lo que pasa

  Nota que puedes remplazer "2" por "INT" o "SIGINT" el nombre de la senal
  Nota tambien que puedes atrpar todos los sinales en la lista exepto el mas famoso, el 9 el de la muerte. Como se llama? (ver > trap -l). Este es imparable y mata si o si un proceso, si condiciones ni bifurcaciones.

  > trap - 2  # Remueve el manipulador del 2 => SIGINT vuelve a su funcion original

  Presiona Ctrl-C


P07: Trap salida de un programa (EXIT)
  Puede ser convniente ejecutra codigo a la salida de un programa.
  Aqui, para no escribir un archivo, vamos a usar un SubShell como programa. Ahora que sabes que son, en realidad otros programas
  > ( trap "echo 'Runned at exit'" EXIT; echo 'Before exit'; exit; echo 'After exit'; )

  Correlo, y sigue lo que pasa. Por supuesto el 'After exit' nunca esta llamado
  Nota que EXIT no es un senal, es una funcionalidad mas de "trap"


P08: Trap cada linea (DEBUG)
  > var=11
  > trap 'echo var = $var' DEBUG  # Nota que las citas son simples, asi el $ no se interpola (todavia). Que psas si las pongo doble
  var=22
  echo 'Cualquier wea'
  > ((var*=2))  # Bobla el valor de var gracias al contexto arithmetico
  trap - DEBUG  # Para la wea

  Nota que DEBUG tampoco es un senal, es una funcionalidad mas de "trap"


P09: Matar no necesariamente mata
  Sino que manda una senal, si esa senal es la 9, eso si que mata!
  > kill $(jobs -p)   # Kill all jobs, nota la substitucion de commando

  Atrapame
  > trap "echo Process $BASHPID received SIGUSR1" SIGUSR1
  > trap "echo Process $BASHPID received SIGUSR2" SIGUSR2

  Mandame una senal a mi mismo (se usa mucho)
  > kill -s SIGUSR1 $$
  > kill -10 $$  # Lo mismo
  > kill -s SIGUSR2 $$

  Ahora en un subshell:
  > (
# Dice hola
echo spawning $BASHPID and sleeping forever;
# Instala un manipulador
trap "echo Process $BASHPID received SIGUSR1" SIGUSR1;
# Duerme, despierta duerme
while true; do sleep 0.1; done
# Corre el subshell en fondo
) &

  Verifica
  > jobs  # Debria haber un job [1]

  Manda la senal SIGUSR1 (10) al primer job => el subshell
  > kill -s SIGUSR1 %1
  > kill -10 %1

  # Ahora terminalo sin condiciones
  kill -9 %1

  Verifica
  > jobs  # No deberia haber ningun job


End:
  Acuerdate:
    - kill no sirve solo para matar sin condiciones, pero para mandar senales que se atrapan con trap, o tienen un manipulador por defecto descrito en el manual.
    - un subshell es un otro proceso que clona todo del shell y desaparace con su estado

  Veremos justamente como se hace este clonaje y que es tipico de la formacion de proceso en Linux (no en Windows)

  Felicitacion por haber hecho tu tarea en casa y leido hasta el final.
  



linux41
-------
System: Explorar: Process, Device: pstree, /dev/zero


+=============================+
| Parte 1 Explorar: Processos |
+=============================+


P01: Lista de processo (ps)
  > ps  # Como ProcesseS da la lista de los procesos
  > ps -aux  # Suelo usar ese, puedes agragar -f para full
  > ps -aux | grep bash  # Y siempre se usa en un tubo


P02: Arbol de processos (pstree)
  > pstree -alp  # -a = muestra la linea de commando del commando, -l = formato largo, -p = muestra el PID

  Redirecionalo en un archivo y lee el archivo
  > pstree -alp > process_tree.txt
  > xdg-open process_tree.txt

  Encuentra tu propio processo: pstree y sus padres

  De forma mas sencilla:
  > pstree -al -s $$
  Muestra especificamente el proceso con PID $$ es decir el presente Shell

  > man systemd


P03: Clonear un proceso (fork)
  La forma que tiene Linux de crear procesos es clonear un proceso (padre). Uno de los clones queda siendo el mismo y el otro llega a ser el hijo. Este rpoceso se hace mediante la llamda systema fork.
  En el Shell, se llama un SubShell, lo que hemos visto en la clase precedente con la substituciones de commando.
  Un subshell se puede generar adentro de "()" y se genera automaticamente cuando el proceso se pone en fondo (con "&") sino no podrias acceder a tu "prompt"hasta que se termine y el proceso no estaria en fondo. Cierto?

  Este ejercicio es para entender el proceso de la herencia. El (proceso) hijo herede del (proceso) padre pero el padre no herede del hijo.

  > var=42  # En el padre
  > echo In father shell: $var
  > (echo in subshell 1: $var; var=31; echo in subshell 2: $var);  # El hijo cambia var
  > echo In father shell: $var  # Pero el padre todavia tiene su var original. Hubo un clonage de la variable var y de mucho mas cosas


P04: Remplazar un proceso (exec)
  Forkear esta bien, pero clonea el proceso, como hago si quiero correr un otro proceso, pro ejemplo cat, wait o vim?
  En este caso se usa el commando exec que hace la llamada de systema del mismo nombre
  > exec cat /dev/urandom
  > exec sleep 2

  Como este proceso se vuelve el proceso padre del emulador de terminal, al acabarse, se ciera la terminal!



+==========================+
| Parte 2 Explore: Device  |
+==========================+

P11: Arbol de archivos (tree)
  Los mismos que pstree para imprimir el arbol de archivos.
  > tree
  Lo uso a veces para escribir documentation de un codigo


P12: Zero a file (dd): descripcion de filefrag
  dd significa "Disk Dump". Es un commando como cat orientado a los bytes y no a los caracteres imprimibles. Es mas bajo nivel => mas dificil de usar pero tiene mas utilidades potencilaes.
  Basicamente si quieres escribir o leer unos bytes en un "archivo" (Formatear, Copiar al usb, Llenar un tunnel ...) es este commando.

  Pero primero planteamos un problema:
  > cd ~/Test  # Anda a jugar
  > echo -e "Secreto de estado:\n\nChile atacara Argentina\n-- Por Bariloche\n-- Manana a las 4pm\n-- Con 20.000 tropas terestres livianas\n\nDespues de lleerlo, destruye este mensaje" > secret.txt  # Escribe un secreto
  > cat secret.txt  # Leer el mensaje, pide destruirlo, pero primero:
  > filefrag -v secret.txt  # Anota el intervalo fisico (que no llaman direcion para no confundir con la RAM). Para mi es: 165776360
  > df  # Anota el nombre del dispositivo de la particion de tu /home. Para mi es /dev/nvme0n1p4
  > cat secret.txt  # Lee el archivo del system de archivo (en el espacio usario)
  > sudo dd bs=4k skip=13004623 count=1 if=/dev/nvme0n1p4  # Lee el sector directamente del disco duro (en el espacio kernel)


P13: Zero a file (dd): Demostracion del problema
  Pero ahora, boramos el archivo:
  > rm secret.txt  # Destruye el archivo
  > cat secret.txt  # Si ya no se ve en el systema de archivo
  > sudo dd bs=4k skip=13004623 count=1 if=/dev/nvme0n1p4  # Pero todavia se ve en el disco duro

  El commando rm solo destruyo el inode. Por eso puede ser muy rapido (ver ejercicio siguiente: escribir un archivo con random).
  Pero no es muy "seguro" porque el contenido del archivo todavia esta en el disco duro. Aun asi, no confies en eso para recuperar tu archivo. Pero no estas seguro que no lo puedan recuperar.
  Para remover el contenido del disco duro, hay que reescribirlo (con zero o random) antes de borrarlo.
  Eso es el ejercicio siguiente:


P14: Zero a file (dd): Forma dura
  Se puede reescribir directamente del disco duro:

  !! Cuidado !! No corres este commando si verificar 7 veces. Puede ser aun peor que el famos rm de la muerte
  > # sudo dd bs=4k count=1 if=/dev/zero of=/dev/nvme0n1p4 seek=33751605 
  Disk Dump
  ByteS: Tamano de un sector mas o menos
  Count: Cuantas veces (1) porque el file pointer avanza
  Input File
  Output File
  Seek: Busca el offset en el output file antes de escribir, es como el skip del output file

  Lo precedente es super complicado y peligroso. Pero ha sido necesario en un SSD. Pero tum como tienes un HD, puedes intentar (sin miedo) lo siguiente:
  > shred -zvu -n 5 secret.txt
  Y verifica que se borro bien del Disco Duro y no solo del systema de archivo

  Entendiste como hemos usado /dev/zero.
  De la misma forma podemos usar /dev/urandom.
  Cual es la differencia?


P15: Zero a file (dd): Usa el manual
  De que sirven la opciones z, v y u de shred?


P16: Crear un archivo grande
  > time dd iflag=fullblock if=/dev/urandom of=big_file.txt bs=32M count=16
  Aumenta el tamano el numero de cuenta (count) si es demasiado rapido

  > ls -lh big_file.txt  # Que tamano es?

  Aparte sobre el sig pipe:
  Mira un poco el archivo:
  > cat big_file.txt | head  # Nota que el commando termina muy rapido
  > cat big_file.txt  # Se demora muchisimo => Ctrl-c
  Te afirmo que el commando cat se termino muy rapido porque head le mando una senal de "Tubo Quebrado".
  Dime cual es el numero de la senal "tubo quebrado". Indicio: 1/ traduscalo en ingles, 2/ man 7 signal, 3/ Buscar (con "/") la traducion en ingles.
  Fin del aparte

  Hypothesis: que esperas de este commando Sera lento o rapido?
  > time rm big_file.txt
  Validacion: tenia razon en tu hypothesis? Porque?

  > time dd iflag=fullblock if=/dev/urandom of=big_file.txt bs=32M count=16
  Hypothesis: que esperas de este commando Sera lento o rapido (Nota yo me equivoque)?
  > cat big_file.txt > /dev/null
  Validacion?


P17: Aleatorio ($RANDOM)
  Para los flojos:
  > echo $RANDOM

  Para algo mas serio
  > cat /dev/urandom  # Ctrl-c, sino jamas se acaba

  La pregunta es, de donde saca aleatorio una machina determinista.
  La repuest es del procesador o de la tajeta madre. Puedes ver como se llama el dispositivo con:
  > cat /sys/devices/virtual/misc/hw_random/rng_available
  o
  > cat /sys/class/misc/hw_random/rng_available

  El nucleo saca el aleatorio de este dispositivo, creando por comodidad un otro dispositivo (un espiece de alias) que se llama /dev/hwrng. Para HardWare Random Number Generator.

  Puedes generar numeros aleatorio a un nivel mas bajo (nivel kernel) con
  > sudo head -c 32 /dev/hwrng | hexdump  # Donde puse el (> hexdump) solo para que se pueda leer (encodificado en numeros hexadecimales)

  O el commando dd
  > sudo dd if=/dev/hwrng of=random.txt bs=1024 count=8
  > cat random.txt

  Nota que leer /dev/hwrng es muchisimo mas lento que leer /dev/urandom porque toma solo los numeros primordiales de la base de entropia, y no los expande como /dev/urandom.

  Todo eso sirve para la cryptografia. Que se puede ver en https, ssh, passwd y systema de archivos ecryyptados (puede ser todo el disco duro, un pdf, un archivo cualquiera, un falso archivo que simula un systema de arvhivo [en este caso hay que hacer tubos en el nucleo = pilotos])

  De todo eso, solo recuerda /dev/urandom


End:
  Felicitacion!

  Hemos visto:
  -- ps, pstree, subshell (fork), exec
  -- /dev/null, /dev/zero, /dev/urandom

  Maniana veremos: monolineas

  Pero antes, tendermos la prueba de medio cyclo

  



linux42
-------
-- Tarea: dd, filefrag, fork, exec


+==================+
|  Explorar: Tarea |
+==================+

P01: Generar unos
  El nodo /dev/zero genera un flujo de bits seteado a 0.
  Pero no existe el nodo /dev/one que generaria un fujo de 1
  > cat /dev/zero | tr '\0' '\377' | hexdump -C
  El commando (> tr) significa TRanspose, cambia un caracter en otro. Ahi el prefijo  significa lee el caracter siguiente con eondage octal.


P02: Instalar un driver
  Nos gustaria tener un archivo /dev/one que genera solo unos tal como /dev/zero genera solo zeros.

  Para estar claro:
  > cat /dev/zero | hexdump -v  # Ctrl-c para acabar
  Genera solo zeros: el numero a la izquierda es offset, la posicion en el archivo.
  Querermos que estos zero sean unos osea F en hexadecimal (que es 1111 en binario)

  Pero /dev/one no existe en el nucleo Linux que es monolitico.
  Se puede instalar pilotos. Pero este no existia, asi que lunes 12 de octubre, lo escribi.

  Ahi esta: https://github.com/tinmarino/dev_one
  Tu mision es instalarlo! Tiempo estimado: 20, 30 minutos.
  Lo interesante es que entiendas la conversacion que sigue, osea donde te metes.

  Un piloto es un programa que vive en el espacio del nucleo, asi que es la mision mas bajo nivel que te tocara. Pero es importante haber metido la manos ahi.

  1/ La diferencia grande entre el espacio usario el espacio nucleo es que en el nucleo, no hay usario! Nadie para decir cuando empezar o acabar un programa. Asi que todo los programa nucleos son servicios (los servicios desafortunamente solo seran visto en la clase 9)
  2/ En el nucleo hay solo un usario: root (la raiz abajo en el nucleo, suena coherente) y tiene acceso a todo tu systema sin que nadie lo pueda vigilar. Asi que si un virus se mete ahi, no lo detectas, ni lo sacas, pero el te espia todo sin que veas ni siquiera que usa el CPU.
     Por lo tanto existe un protecion adicional (en todos los sistema: Windows, Linux, Mac y Android) que obliga los fabricantes. Esta protecion es una firma. Si tu firma tiene autoridad, se instala sencillamente, sin ruido. Si no (como en mi caso), tienes que pedir al usario desabilitar el "Secure boot" es su bios o abilitar la firma reiniciando su programa y interactuando a nivel casi electronico: en el UEFI (nuevo BIOS) mas bajo que el hypevisor que es mas bajo que el kernel, lo que un virus no puede hacer ya que no tiene las manos sobre el compu.
  3/ Para finalmente interactuar con el usario final (sino serian inutiles), los pilotos contruyen archivos y leer o escribir en estos archivos dispara las funciones deseadas, aqui escribir 1111111 infinitamente y rapidamente.

           .-""""-.
          ////||\\  Humans, some mammels
          |/      \|  Carbon based and hard to predict
Ring 4   (  @   @   )
          |   C    |
           \  ==  /
            `|--|`
              ^
              |
           +--------------------+ Easy to write and isolate
Ring 3     | Unpriviledged Code | Safe fail
           +--------------------+ Ex: BaSh
              |
           +-----------------+ Hard to isolate
Ring 2     | Priviledge Code | but that can be an advantage
           +-----------------+
              |                          USERLAND
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |                          KERNELLAND
           +---------------+
Ring 1     | Device Driver | In kernelland, get access to
           +---------------+ the hardware abstracion layer
              |              Can be compiled seprately as module
              |
           +--------------+ Monolyte: /boot/vmlinuz-5.4.0-48-generic
Ring 0     | Linux Kernel | Imposible to isolate, must shutdown to change
           +--------------+
              |                          KERNELLAND
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |                          UNDERWORLD
              |
           +------------+ CPU new funcionality
Ring -1    | Hypervisor | for enhanced virtualisation
           +------------+
              |
           +------------------------+  UEFI, ex BIOS
Ring -2    | System Management Mode |  (press f2 at boot)
           +------------------------+
              |
              |                          UNDERWORLD
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |                          E-SPACE (Harware)
              |
           +------------+ Embeded in some
           | Micro Code | micro controlers
           +------------+ = (μCPU, μRAM, μSSD)
              ^
              |
           _______
          | _____ | Cober circuits. Made by computer
          ||_____|| Programmed with lines of code
          |  ___  | In VHDL language
          | |___| |
          |       | Crafted in China or Vietnam
          |       |
          |       |
          |       |
          |       |
          |_______|


P03: Monitoreo de processos (top)
  > top  # q to exit, enter to refresh faster
  En una terminal:
  [+] Es facil ejecutar, aun a distancia (ssh sin configuracion)
  [-] Es feo y (muy) complicado de usar (con el teclado)

  Tienes una applicacion llamada "System Monitor"?


P04: Encuentra tus limites (ulimit)
  Show me all your limit:
  ulimit -a  # ulimit = Your Limit, -a = all


P05: Explota tus limites (fork bomb)
  Prepara tu machina, real y virtual porque vas a tener que reiniciarla.
  Eso se llama un "fork bomb".
  Cada vez que corre la function, lanza dos subprocesos en fondo:
  Debido al tubo "|" y al fondo "&" lanza la funcion como proceso.
  Por lo tanto duplica sus recursos a cada invocacion y eso explota la RAM, hace perder la cabeza al planificador (scheduler). Y va a bloquea tu compu.

  Si no quieres bloquear tu compu, confia en mi y no lo corres
  > bomb() {
bomb | bomb &
}; bomb


P06: Limita tus limites y evita la explosion
  > ulimit -u 5000  # Limita el numero de proceso del shell a 5000
  > bomb() { bomb | bomb & }; bomb  # Ahora si corre la bomba
  Ciera la terminal para matar en cadena esta cadena de procesos

  <= Accuerdate (clase 4) que cerar un shell envia SIGTERM a todo sus hijos, y que el comportamiento por defecto al recebir una senal SIGTERM est terminar.

  Has visto el "fork bomb" un tipo de ataque primitivo que provoca una negacion de servicio (Denial Of Service DOS) osea quebra la macina del adversario y has visto como defenderse de este ataque (acuerdate de "Your limits")


P07: Cuanta memoria libre (free)
  > free -h
  H como "human read" con el Gi. Como "du -h".
  Mas detalles:
  cat /proc/meminfo


End:
  Asi acabas la primea mita de la clase intensiva de Linux. Felicitacion!

  Manana: la prueba de mitad de clase.
  Asi que te toca revisar. Puedes usar el commando que definimos en la clase 042:

  > jim --doc | grep -ao '> \(sudo \)\?\w\+' | sed 's/sudo //' | cut -c 3- | sort -u | awk '{print "apropos -l \"^" $1 "$\""}' | bash 2>&1 | grep -v "nothing appropriate" | tee command_index.txt
  > xdg-open command_index.txt

  



linux43
-------
-- Examen: medio cyclo


+============+
| Examen 1/2 |
+============+
  
P01: Describe lo que pasa cuando apretas Ctrl-Z mientras un commando se ejecuta.
    
P02: Como puedes ver el historico de los commandos que hiciste?
    > history
    
P03: Que significa SSH?
    Secure SHell
    
P04: Que es el kernel Linux?
    El Kernel de Linux es un software de sistemas de bajo nivel cuya función principal es administrar los recursos de hardware para el usuario.
    También se utiliza para proporcionar una interfaz para la interacción a nivel de usuario.
    Esta interface se puede acceder mediante archivos (file) y llamada systema (system call o syscall).
    
P05: Que es la cuenta root?
    La cuenta raíz (root) es como una cuenta de administrador de sistemas y le permite un control total del sistema.
      Aquí puede crear y mantener cuentas de usuario, asignando diferentes permisos para cada cuenta.
      Es la cuenta predeterminada cada vez que instala Linux.
      Su numero de usario es 0. Se puede averiguar en /etc/passwd
    
P06: Como se copia pega en la terminal? Porque no se puede usar Ctrl-C?
    Se copia pega con selection y boton del medio (mediante el "selection clipboard").
    O con Ctrl-Shift-C y Ctrl-Shift-P.
    No se puede usar Ctrl-C porque desde 1970, sirve para mandar la segnal SIGINT (2) que interumpe el processo corriendo en primer plano (si es otro que el shell).
    
P07: Como saber cuanta RAM libre tiene el systema?
    > free -m
    
P08: Como cambiar los permisos (Read, Write, Execute) de un archivo?
    > chmod +x script.sh  # Para dar el derecho en escritura al dueno del archivo
    
P09: Que son los archivos que empiezan con un punto?
    En general, los nombres de archivo que están precedidos por un punto son archivos ocultos.
    Estos archivos pueden ser archivos de configuración que contienen datos importantes o información de configuración.
    Establecer estos archivos como ocultos hace que sea menos probable que se eliminen accidentalmente.
    
P10: Que significa GUI y CLI? Que es la diferencia entre los 2?
    GUI: Graphical User Interface
    CLI: Command Line Interface
    El GUI, se usa de forma graphica, se puede usar el raton, se puede incluir imagenes. Como Firefox.
    EL CLI, se usa con un prompt, con lneas de commando. Como Bash interactivo (el prompt, tambien llamado shell).
    
P11: Que hace el commando pwd? Que significa?
    Print Working Directory.
    Escribe el directorio actual de trabajo en la salida estandar.
    Como > echo $PWD.
    
P12: De que sirve el commando sudo?
    Sirve para ejecutar los argumentos como un commando hecho por el usario root.
    
P13: Como se llama el operador "|"? Que hace?
    El operador "|" se llama "tubo" (en ingles "pipe").
    Redirection la salida estandar del commando que lo precede en la entrada estandar del commando que lo sigue.
    
P14: De que sirve el commando "grep"?
    Sirve para filtrar las lineas de su entrada estandar y selecionar solo las que contienen un patron especifico.
    Se especifica el patron como argumento del commando.
    Ex: > grep palabra_que_busco
        > grep -v palabra_no_quiero_ver  # v como inVert
    
P15: Como se escriben commentario en una linea de commando Bash?
    Los comentarios se crean escribiendo el símbolo # antes del texto del comentario real.
    Esto le dice al shell que ignore completamente lo que sigue.
    Por ejemplo, "# Esto es solo un comentario que el shell ignorará".
    
P16: Como se ejecuta mas de un commando en una linea?
    Se puede combinar varios comandos separando cada comando o programa con un símbolo de punto y coma (";").
    Por ejemplo, se puede emitir una serie de comandos de este tipo en una sola entrada:
    > ls –l; cd ..; ls –a MYWORK
    
P17: Escriba un comando que busque archivos con una extensión "c" y que contenga la cadena "apple".
    Hay distintas formas. La del profe es:
    > ls | grep '*.c' | grep 'apple'

    La del sitio era:
    > find ./ -name "*.c" | xargs grep –i "apple"
    
P18: Escriba un comando que muestre todos los archivos .txt, incluido su permiso individual.
    > ls -al *.txt  # a = All: muestra los archivos escondidos, l = List, muestra los permisos, la fecha de creacion, el dueno
    
P19: Que esta mal en cada uno de los siguientes commandos: a/ "ls -l-s" b/ "cat file1, file2" c/ "ls - s Factdir"? Consejo: cada uno tiene algo mal.
    a) debe haber espacio entre las 2 opciones: "ls -l -s" o nada "ls -ls"
    b) no use comas para separar argumentos: "cat file1 file2"
    c) no debe haber espacio entre el guión y la etiqueta de la opción: "ls –s Factdir"
    
P20: Cuál es el comando para calcular el tamaño de una carpeta?
    La repuesta es "du" como Disk Usage.
    Ex: > du –sh folder
    
P21: Cómo se puede agregar un archivo a otro en Linux?
    > cat file2 >> file1  # Agrega el contenido de file1 en file2
    o
    > cat file1 file2 > file3  # Concatena fil1 y file2 en file3, creando este ultimo.
    
P22: Cómo se puede crear un directorio?
    > mkdir folder  # Para crear el directorio con nombre folder
    
P23: Escribe un commando que permite ver el contenido del archivo "file.txt".
    > cat file.txt  # Para imprimir su contenido en la terminal (salida estandar si no hay tubos)
    o
    > xdg-open file.txt  # Para abirlo en el programa por defecto
    o
    > vi file.txt  # Para abrilo en el editor de texto "vi" que vermos despues
    
P24: Suponemos que hemos escribido la funcion "work" que hace un tipo de trabajo demoroso. Cual es la differencia entre el commando "work" y el commando "work &" con una "&" al final?
    Agregando una "&" al final corre el programa (o la funcion) en segundo plano, asi la entrada estandar de la terminal vuelve al usario.
    
P25: Como puedes instalar un programar en lubuntu? Por ejemplo "git".
    > sudo apt install git
    
P26: Cual es el commando que permite acceder a la documentacion de un commando?
    man como MANual
    
P27: Escribe el commando para renombra el archivo "file1" en "file2"
    mv file1 file2
    
P28: Escribe el commando para remover el archivo "file with spaces.txt". Cuidado que el archivo tiene espacio en su nombre.
    Hay que poner citas. Simple o doble da lo mismo porque no hay $ en su nombre y no lo interpolamos
    > rm 'file with spaces.txt'
    Si se olvida loas citas, el commando "rm" va a remover los archivos "file", "with" y "spaces.txt" lo que no es el objectivo.
    
P29: Como saber la version de tu kernel?
    > uname -a  # Les pides al kernel: give me "your name" completo (-a = all)
    
P30: A que corresponde el descriptor de archivo numero 0?
    0: Entrada Estandar (StdIn)
    1: Salida Estandar (StdOut)
    2: Salida de "Errores" (StdErr)
    
P31: Escribe un commando que escribe en mensage "Message with spaces" en la terminal.
    > echo "message with spaces"  # Las citas pueden ser simple ya que no hay $ ni interpolacion
    
P32: Escribe un comando que crea el archivo file.txt con el contenido "content".
    > echo content > file.txt
    
P33: Escribe el commando que permite abrir un shell en la machina con IP 192.168.0.9 para el usario jim.
    > ssh jim@192.168.0.9
    
P34: Cual es la salida del commando "echo $(( 2 + 3 * 2 ))"?
    "8": $\(\(\)) hace la interpolacion arithemtical de 2 + 3 * 2.
    La mutiplicacion tiene prioridad sobre la adicion (como saben los alumnos con papel y lapiz). 3 x 2 = 6. 6 + 2 = 8
    
P35: Cual es la salida del commando "var=42; echo '$var'"?
    "$var": Porque las citas simple no interplan las variable.
    La trampa era responder 42 como para  "var=42; echo "$var"" (con citas doble)
    



linux51
-------
Syntax: Monolinea: Recreo


+===========+
| Monolinea |
+===========+

Pare la primera clase de la segunda parte, vamos a jugar!
Un escript Monolinea (One Liner) es un programa que mide una linea.
Tiene ventaje en la portabilidad (facil copiar pegar, buscar en tu historial) y genericidad (no es muy personalisado).
Los commandos Linux responden a la filosofia: "hacer una cosa y hacerla bien".
Entonces, para las tareas del cotidiano, estas operaciones atomicas suelen combinarse en tubos, ejecuciones en serie o paralelo en lo que se llama monolineas.

Haga triple click para selectionar la linea

for i in {1..10}
do
    echo 
done

for i in {1..10} ; do echo  ; done

for i in {1..100} ; do touch File-${i} ; done
ls File-* | wc -l


P11: Descarga el libro Advanced Bash Scripting
wget -qO- https://tldp.org/LDP/abs/abs-guide.txt.gz | gunzip - > abs.txt
  wget: web get:
    -q = suprime la salida estándar (los mensaje)
    -O- es del alfabeto y no cero, escribe en la salida estándar lo que descargo
  gunzip: despaquetea
    - = entrada estandar
  > cat abs.txt  # Un archivo con texto humano (ingles)


P12: Muestra los 10 archivos abiertos los mas largos
lsof / | awk '{ if($7 > 1048576) print $7/1048576 "MB" " " $9 " " $1 }' | sort -n -u | tail


P13: Tira un dado:
echo Dado: $(shuf -i 1-6 -n 1)


P14: Escanea todo los puertos abiertos de todas las interfaces accesibles
ifconfig -a | grep -Po '\b(?!255)(?:\d{1,3}\.){3}(?!255)\d{1,3}\b' | xargs nmap -A -p0-


P15: Busca las palabras mas utilizadas
tr -c a-zA-Z '\n' < abs.txt  | sed '/^.\{1,2\}$/d' | sort | uniq -i -c | sort -n


P16: Busca los procesos que usan mas RAM
ps aux | awk '{if ($5 != 0 ) print $2,$5,$6,$11}' | sort -k2n


P17: Busca los 10 comandos los mas usados
awk '{print $1}' ~/.bash_history | sort | uniq -c | sort -n
  O
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10


+--------------------+
| Efectos especiales |
+--------------------+
Ctrl-l : cLear terminal (mas rápido que escribir "> clear")

P20: 10 PRINT CHR$(205.5+RND(1)); : GOTO 10
  10 PRINT es un libreo de 300 paginas sobre esta linea de comando.
  Arriba en BASIC, abajo en BaSh, mas ahi: https://10print.org/
  Bienvenido en el mundo del "hackeo"
    <= palabra que se usa tambien para referirse al escribir programas muy pequeños y elegantes
while :; do printf \\$(printf '%o' $[47+45*(RANDOM%2)]); done


Imprime la table de caracteres ascii
for i in {32..255};do ((i%16==0))&&echo;printf "\\$(printf "%o" $i) ";done|iconv -f cp437 -t utf8
  O
awk 'BEGIN {for (i = 32; i < 127; i++) printf "%3d 0x%02x %c\n", i, i, i}' | pr -t6 -w78
  Pero ahi, mejor leer:
  > man ascii


Extranas tu vieja TV
P=(' ' █ ░ ▒ ▓);while :;do printf "\e[$[RANDOM%LINES+1];$[RANDOM%COLUMNS+1]f${P[$RANDOM%5]}";done


El efecto del caballero
while :;do for i in {1..20} {19..2};do printf "\e[31;1m%${i}s \r";sleep 0.02;done;done


Graphicos: Mosaicos
for((y=0;y<$[LINES-1];y++));do for((x=0;x<=$COLUMNS;x++));do printf "\e[${y};${x}f\e[38;5;$[232+(x^y)%24]m\u2588";done;done


Graphics: Math: Fractal de Madelbrot
  Nos acercamos del arte, el autor dejo su firma.
  Copia todo el parafo que sigue:

p=\>\>14 e=echo\ -ne\  S=(S H E L L) I=-16384 t=/tmp/m$$; for x in {1..13}; do \
R=-32768; for y in {1..80}; do B=0 r=0 s=0 j=0 i=0; while [ $((B++)) -lt 32 -a \
$(($s*$j)) -le 1073741824 ];do s=$(($r*$r$p)) j=$(($i*$i$p)) t=$(($s-$j+$R));
i=$(((($r*$i)$p-1)+$I)) r=$t;done;if [ $B -ge 32 ];then $e\ ;else #---::BruXy::-
$e"\E[01;$(((B+3)%8+30))m${S[$((C++%5))]}"; fi;R=$((R+512));done;#----:::(c):::-
$e "\E[m\E(\r\n";I=$((I+1311)); done|tee $t;head -n 12 $t| tac  #-----:2 O 1 O:-


Graphicos: BaSh on fire
  Reconoces algunos commandos? So todos avanzados.
  
X=`tput cols` Y=`tput lines` e=echo M=`eval $e {1..$[X*Y]}` P=`eval $e {1..$X}`;
B=(' ' '\E[0;31m.' '\E[0;31m:' '\E[1;31m+' '\E[0;33m+' '\E[1;33mU' '\E[1;33mW');
$e -e "\E[2J\E[?25l" ; while true; do p=''; for j in  $P; do p=$p$[$RANDOM%2*9];
done;O=${C:0:$[X*(Y-1)]}$p;C='' S='';for p in $M;do #  _-=[ BruXy.RegNet.CZ ]=-_
read a b c d <<< "${O:$[p+X-1]:1} ${O:$[p+X]:1} ${O:$[p+X+1]:1} ${O:$[p+X+X]:1}"
v=$[(a+b+c+d)/4] C=$C$v S=$S${B[$v]}; done; printf "\E[1;1f$S"; done  # (c) 2012


Graphicos: BaSh on fire
  Dibujos desde la nuve.
  
curl -L http://git.io/unix$cend  # UTF8 encoded
curl -L http://artscene.textfiles.com/ansi/scene/am-ice.ans 2> /dev/null | iconv -f cp437 -t utf-8  #  CP-437 encoded
curl -L http://artscene.textfiles.com/ansi/scene/bigtime3.ans 2> /dev/null | iconv -f cp437 -t utf-8
curl -L http://artscene.textfiles.com/ansi/scene/fconfigs.ans 2> /dev/null | iconv -f cp437 -t utf-8


Graphicos: Enter the matrix

echo -e "\e[1;40m" ; clear ; while :; do echo $LINES $COLUMNS $(( $RANDOM % $COLUMNS)) $(( $RANDOM % 72 )) ;sleep 0.05; done|awk '{ letters="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()"; c=$4; letter=substr(letters,c,1);a[$3]=0;for (x in a) {o=a[x];a[x]=a[x]+1; printf "\033[%s;%sH\033[2;32m%s",o,x,letter; printf "\033[%s;%sH\033[1;37m%s\033[0;0H",a[x],x,letter;if (a[x] >= $1) { a[x]=0; } }}'

(echo -e "\033[2J\033[?25l"; R=`tput lines` C=`tput cols`;: $[R--] ; while true
do ( e=echo\ -e s=sleep j=$[RANDOM%C] d=$[RANDOM%R];for i in `eval $e {1..$R}`;
do c=`printf '\\\\0%o' $[RANDOM%57+33]` ### http://bruxy.regnet.cz/web/linux ###
$e "\033[$[i-1];${j}H\033[32m$c\033[$i;${j}H\033[37m"$c; $s 0.1;if [ $i -ge $d ]
then $e "\033[$[i-d];${j}H ";fi;done;for i in `eval $e {$[i-d]..$R}`; #[mat!rix]
do echo -e "\033[$i;${j}f ";$s 0.1;done)& sleep 0.05;done) #(c) 2011 -- [ BruXy ]


Fork bomb! No lo corres!
  Te acuerdas de la bomba de fork que llena tus recursos si no usas ulimit?
  Se puede minificar asi:
:(){:|:&};:


+----------------+
| Sound to Music |
+----------------+

41: Sonido pito
echo -e "\a"
The -e (Escape) is fundamental to enable escape sequence. You can also printf "\a"
  Or, after installing sox
play -n synth 0.1 sine 880 vol 0.5



42: Musica desde el chaos
cat /dev/urandom | hexdump -v -e '/1 "%u\\n"' | awk '{ split("0,2,4,5,7,9,11,12",a,","); for (i = 0; i < 1; i+= 0.0001) printf("%08X\\n", 100*sin(1382*exp((a[$1%8+1]/12)*log(2))*i)) }' | xxd -r -p | aplay -c 2 -f S32_LE -r 16000


Musica 2
python3 -c "while 1:locals().setdefault('t',0);print(chr((((t*((ord('36364689'[t>>13&7])&15)))
//12&128)+(((t>>12)^(t>>12)-2)%11*t//4|t>>13)&127)),end='');t+=1" | aplay -r 44100


Musica 3: Bytebeat From fractal
  Bytebeat (Viznut 2011). Es una forma de generar musica de codigo, basada en la propriedaddes de:
  1/ Fractales
  2/ Bug (overflow y side effect)
  3/ Dicretisacion

  Mira el fractal: "Triangulo de Sierpinski" (t&t>>8):
  (Nota que para annular el efecto de retorno a la linea > setterm -linewrap off or > tput rmam y > tput smam para restorar.
  
for((y=63;y>0;y-=2));do s="";for((x=64;x--;));do(((x-y/2)&y))&&s+=" "||s+="Δ";done;echo "$s";done
  Convertido En sonido, seria:
for((t=0;;t++));do((n=(
t&t>>8
), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c";done| aplay 


Musica 3: Bytebeat VizNut 2011
  Esta melodia la llame "Mysterie trans".
  
for((t=0;;t++));do((n=(
(t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c";done| aplay 


Musica 4: Corporate Bullshit Generator
  Permanent Link: http://cbsg.sf.net
  Please install libttspico-utils, a better speach generator than espeak
  
curl -s http://pasta.phyrama.com:8083/cgi-bin/live.exe    | grep -Eo '^<li>.*</li>' | sed s,\</\\?li\>,,g | shuf -n 1 | tee /dev/stderr | xargs -I foo -0 pico2wave -w /tmp/blah.wav foo; play  /tmp/blah.wav &> /dev/null


P99: Just Another Perl Hacker
  El climax del codigo: monolinea, elegante, ofuscado, graficos
  Se encuentra con el nombre Perl Japh (wikipedia: https://en.wikipedia.org/wiki/Just_another_Perl_hacker)

  Perl: Practical Extraction and Reporting Language => Un idioma que busca patrones y reporta de forma elegante (el hijo de sed)
  Japh: Just Another Perl Hacker => Una competencia amical de la forma mas elegante de escribir esta misma frase.

  Aqui tu maestro, escribio uno para tu batismo. No lo intentes entender: es magia oscura.
  Paciencia mi aprendiz ...
  
perl -e 'use Time::HiRes"usleep";$|=@q=(a..z," ");print"\e[1m\e[31m";$_="hwjdai 5mcn pkiaasea dr";while(s/(..)(.)//){ $_.=$1; $s.=$2 };@w=("$s"=~/./g);while("@w"ne"@e"){$e[$_]eq$w[$_]or$e[$_]=$q[rand@q]for+0..$#w;print"\r@e";usleep+1e5};print"\e[0m\n"'


End:

  



linux52
-------
-- Tarea: Monolinea: Ciclo de vida del desarrollo de programas


+==================+
| Monolinea: Tarea |
+==================+

Educar no es llenar un balde, sino encender un fuego. (Montaigne)
Cabros esto no prendió. (Clemente Pérez)
El fuego tiene que "estar y (per)durar". (Legión extranjera)
Y para eso, aprender y trabajar tiene que ser divertido. Ver gamificacion. (Microsoft)

En esta clase, vamos a hacer un utilitario para leer bytebeats!


P00: Plan
  Seguiremos el Ciclo de vida del desarrollo de programas:
  1. Ideas:
    a. Un proyecto, útil, incremental
    b. Algo lúdico, artístico o interactivo, visual, auditivo
    c. Algo en la terminal en un solo idioma
    => Ya esta decidido, un lector de música!
  2. Requerimientos:
    a. Que no exista ya, y que se pueda vender
    b. Correr en Termux y Linux,
    c. Tener una interfase sencilla
    d. Tener melodía ya cargadas y poder agarrar otras
    e. Dejar espacio para mejoras (tipo guardar músicas)
  3. Diseño:
    a. Separar el código de los datos
    b. Leer música según un tubo hasta el lector:
       Así ningún archivo temporario es necesario
    c. Usar dialog para la interfase terminal
  4. Desarrollo:
    * Metodología Ágil
  5. Testeo:
    * Paso a Paso, en el plan de fases
  6. Despliegue:
    * Termux y Linux, también en 192.168.0.9
  7. Mantenimiento
    * Deprenderá de los errores del curso

  Lo que hay que recordar de todo eso es: no precipitarse y escribir código enseguida.
  De hecho en la misma escritura del código, se empieza con comentarios y prototipos.


P01: Instalar Termux sobre Android
  Termux es un emulador de terminal en Android.
  Como es difícil ser el usuario raíz (root) en Android, hay algunas diferencias.
  Las aplicaciones de Termux corren básicamente en un entorno con cambio de raíz (mas siguiente clase).
  Mas Ahi: https://wiki.termux.com/wiki/Differences_from_Linux

  Hacker's Keyboard es un teclado completo, con las flechas direccionales, Ctrl, Esc ...

  1/ En tu celular: Instala Termux
  1/ En tu celular: Instala Hacker's Keyboard
  2/ En Termux: instala "sox"
  3/ En Termux: instala "openssh-server"
  4/ En Termux: "ip address"
  5/ En Termux: corre "sshd"
  6/ En Lubuntu: Connectate a Termux:
    > ssh -p 8022 192.168.0.5
    Mas: https://wiki.termux.com/wiki/Remote_Access


P02: ALSA, OSS and SOX
  OSS: Open Sound System, es la antigua tecnología que usaban los Unix para correr sonido, se usa mediante lectura/escritura en /dev/dsp
  ALSA: Advanced Linux Sound Architecture, es el nuevo sistema de sonido en el núcleo Linux. Donde esta Linux esta Alsa. Se usa
  SOX: Sound eXchange: La navaja suiza de manipulación de audio (apt install sox)

  Nuestro problema aquí es que la interfase (núcleo) de Alsa no es disponible porque 1/ esta encapsulada en algo privado de Google y 2, el núcleo no es disponible directamente por no ser root.
  Desafortunadamente, el comando aplay (para alsa lee), ya no existe en Termux. Tenemos que usar sox que es mas versátil y desplegable.
  En la linea:

  
for((t=0;;t++));do((n=(
(t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c";done| aplay

  Remplazamos el tubo final: "| alsa" por "| sox -t raw -b 8 -e unsigned -c 1 -r 8000 - -t wav - | play -"

  Lo que nos da
  
for((t=0;;t++));do((n=(
(t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c";done|\
sox -t raw -b 8 -e signed -c 1 -r 8000 - -t wav - | play -


P03:bytebeat, una función de lectura
  Si "aplay" es presente, lo usamos, sino usamos la linea enorme de sox.
  Esta vez, lo escribo yo. Podrás Volver aquí en la clase 8,
  Abre un archivo "zik.sh". Por ejemplo > xdg-open ., botón derecho create file.

  Importante: Tu archivo debe empezar (primera linea) por el shebang: #!/bin/bash que dice a Linux que interpretador debe correr para ejecutar este código.
  También debe tener el derecho de ejecución > chmod +x zih.sh.
  
  #!/bin/bash

  echo "Executing $0"

  Guárdalo, ejecútalo > bash zik.sh o simplemente > zik.sh. El segundo comando funciona solo porque 1/ El archivo es ejecutable y 2/ pusiste un shebang.
  $0 se refiere al comando ejecutado, $1 al primer argumento, $2 al segundo ...

  En zik.sh, escribe la función (entre la flechas):
  -->
byteplay(){
  # Play the equation given as parameter
  # TODO make the function works on Termux
  for((t=0;;t++));do((n=(
  ((t >> 10) & 42) * t
  ), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c";done| aplay
}

# We call the function for testing
# TODO removes me
byteplay 't*(42&t>>10)'
  <--

  Ejecuta el script!
  Anota hemos escrito comentarios, unos con TODO para no olvidar lo que queda por hacer.
  Volveremos ahí después.
  Remover la llamada las 3 ultimas lineas y corre en el shell:
  
source zik.sh  # incluye la funcion en tu shell
bytebeat 't*(42&t>>10)'  # Corre la funcion


P05: La interfase
  Podemos correr música, ahora hay que dejar el usuario elegir que quiere correr.
  Como trabajamos con mejorar incrementales, vamos a incluir la lista en el código.
  --> 
bytegui(){
  # Ask user for the equation to play (in list)
  # Require: dialog

  # Define list (with associative array)
  declare -A bytelist=(
    ['42 melody']='t*(42&t>>10)'
    ['Sierpinski']='t & t/256'
    ['StarLost']='((t % 255) ^ (t % 511)) * 3'
    ['Mistery Trans']='(t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)'
  )

  # Create array with both key and value, to give to dialog
  declare -a bytekeyval
  for key in "${!bytelist[@]}"; do
    bytekeyval+=("$key" "${bytelist[$key]}")
  done

  # Get user input
  name=$(dialog \
    --backtitle "ByteBeater" \
    --clear \
    --menu "Choose equation to bytebeat!" 0 0 "${#bytelist}" \
    "${bytekeyval[@]}" \
    --output-fd 1 \
  )

  # Play melody
  equation="${bytelist[$name]}"
  echo "Playing: $name => $equation"
  byteplay "$equation"
}

bytegui
  <--

  Ejecuta: > bash zik.sh
  Hicimos casi una iteración de desarrollo incremental:
    falta el desplegar que no mostraría que no funciona en Android
  Funciona? Que bueno, si es el caso, es un buen momento para una pausa.

  Antes de la pausa, preparamos lo que haremos después, así las ideas vendrán sola.
  1/ Que funcione en Android
  2/ Separar el código de los datos (tener un archivo de datos)
  3/ Desplegar en Android


P06: Lector de música mas versátil
  Hemos visto (P02) que "aplay" no funciona en Termux.
  Si "aplay" no esta presente, tenemos que usar "sox"
  Remplaza la función byteplay por la siguiente donde el comando del lector es una variable (evaluado para que el tubo se ejecute => eso esta afuera del enfoque de esta clase)

  -->
byteplay(){
  # Determine the sound reader present
  cmd="aplay"
  # If aplay exists (Linux) => just pass
  if command -v aplay > /dev/null; then
    :
  # Else, If sox command exists (Android) => use the big, hacky pipe
  elif command -v sox > /dev/null; then
    cmd="sox -t raw -b 8 -e signed -c 1 -r 8000 - -t wav - | play -"
  # Otherwise (Problem) => Notify user to install sox (in StdErr)
  else
    >&2 echo "ERROR: Cannot reproduce music on your device !"
    >&2 echo "Please install sox => apt install sox"
    exit 1
  fi

  # Play the equation given as parameter
  for((t=0;;t++));do((n=(
  $1
  ), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c"; done | eval $cmd
}
  <--

  Todavía funciona en Linux ?


P07: Separación códigos / datos
  Hemos escrito los datos (canciones) directamente en una cuadra Bash con la sintaxis especifica de Bash, ahí:

  # Define list (with associative array)
  declare -A bytelist=(
    ['42 melody']='t*(42&t>>10)'
    ['Sierpinski']='t & t/256'
    ['StarLost']='((t % 255) ^ (t % 511)) * 3'
    ['Mistery Trans']='(t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)'
  )

  Eso Se llamar hardcode o incluir en duro los datos y esta muy mal!
  La dificultad para: agregar canciones, compartir los datos con un programa, digamos en JavaScript son unos ejemplos de lo malo que es: hay 40 ejemplos mas.
  Es casi la regla 1 => Separa los datos del código!

  Ok, Ok, tranquilo profe, lo vamos a separar.
  Aqui, igual dejaremos los datos en el archivo zik.sh asi sera mas facil transportar, pero lo vamos a poner en un formato independiente del idioma (aqui Bash).
  El formato sera: "Nombre de la muscia : ecuacion" osea usaremos un ":" como separador. Como para la variable de entorno $PATH, no me crees => > echo $PATH.

  Primero Escribe la lista => Copia esta función arriba del archivo zik.sh
  -->
listtube(){
  # Using "Here Document"
  cat << 'EOH'
    42 melody      : t*(42&t>>10)
    Sierpinski     : t & t/256
    StarLost       : ((t % 255) ^ (t % 511)) * 3
    Mistery Trans  : (t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
    Hard Carry     : t*(t^t+(t>>15|1)^(t-1280^t)>>10)
    DickJockey     : (t*(t>>5|t>>8))>>(t>>16)
    Nimpho Piano   : t*(((t>>9)&10)|((t>>11)&24)^((t>>10)&15&(t>>15)))
EOH
}
  <--

  Despues remplaza la definicion de bytelist (citado arriba) en bytegui.
  Replazala por

  -->
  # Define list (with associative array) <= tubelist
  declare -A bytelist=()
  while read -r line; do
    # Get key <= before the first ":"
    key="${line%%:*}"
    # Remove trailing whitespace characters
    key="${key%"${key##*[![:space:]]}"}"

    # Get value <= after the first ":"
    value="${line#*: }"

    # Set array
    bytelist[$key]="$value"
  done <<< "$(listtube)"
  <--

  Donde vez, al final que el ciclo toma como entrada la substitución de comando de listtube, la función que definiste.
  Este símbolo "<<<" significa un Here String. Hice este código con una retiración y no un tubo porque el tubo crea un subshell del cual no pude sacar la variable bytelist. Lo que es desafortunado ya que era el objetivo. Acuérdate que los subshells no pueden modificar las variables de sus padres y que los tubos generan subshells


P08: Resultado final
  Casi terminaste el segundo ciclo de desarrollo. Hagamos una sincronización.
  El código debería ser parecido a:

#!/usr/bin/env bash

listtube(){
  # Using "Here Document"
  cat << 'EOH'
    42 melody      : t*(42&t>>10)
    Sierpinski     : t & t/256
    StarLost       : ((t % 255) ^ (t % 511)) * 3
    Mistery Trans  : (t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
    Hard Carry     : t*(t^t+(t>>15|1)^(t-1280^t)>>10)
    DickJockey     : (t*(t>>5|t>>8))>>(t>>16)
    Nimpho Piano   : t*(((t>>9)&10)|((t>>11)&24)^((t>>10)&15&(t>>15)))
EOH
}

byteplay(){
  # Determine the sound reader present
  cmd="aplay"
  # If aplay exists (Linux) => just pass
  if command -v aplay > /dev/null; then
    :
  # Else, If sox command exists (Android) => use the big, hacky pipe
  elif command -v sox > /dev/null; then
    cmd="sox -t raw -b 8 -e signed -c 1 -r 8000 - -t wav - | play -"
  # Otherwise (Problem) => Notify user to install sox (in StdErr)
  else
    >&2 echo "ERROR: Cannot reproduce music on your device !"
    >&2 echo "Please install sox => apt install sox"
    exit 1
  fi

  # Play the equation given as parameter
  for((t=0;;t++));do((n=(
  $1
  ), d=n%255,a=d/64,r=(d%64),b=r/8,c=r%8));printf '%b' "\\$a$b$c"; done | eval $cmd
}

bytegui(){
  # Ask user for the equation to play (in list)
  # Require: dialog

  # Define list (with associative array) <= tubelist
  declare -A bytelist=()
  while read -r line; do
    # Get key <= before the first ":"
    key="${line%%:*}"
    # Remove trailing whitespace characters
    key="${key%"${key##*[![:space:]]}"}"

    # Get value <= after the first ":"
    value="${line#*: }"

    # Set array
    bytelist[$key]="$value"
  done <<< "$(listtube)"

  # Create array with boeth key and value, to give to dialog
  declare -a bytekeyval
  for key in "${!bytelist[@]}"; do
    bytekeyval+=("$key" "${bytelist[$key]}")
  done

  # Get user input
  name=$(dialog \
    --backtitle "ByteBeater" \
    --clear \
    --menu "Choose equation to bytebeat!" 0 0 "${#bytelist}" \
    "${bytekeyval[@]}" \
    --output-fd 1 \
  )

  # Play melody
  equation="${bytelist[$name]}"
  echo "Playing: $name => $equation"
  byteplay "$equation"
}

bytegui

exit 0


P08: Despliegue en Termux
  Copia este código hasta Termux y ejecútalo ahí:

  En Linux:
  > ip address
  Debieria darte algo como 192.168.0.14 si no es el caso remplazalo, si no tienes la mascara de red 192.168 es que tu adaptador de red VirtualBox no esta en modo puente. Recofiguralo.

  En Termux:
  scp jim@192.168.0.14:Test/zik.sh .
  Remplaza el IP y el camino si necesario.
  Entra la clave
  Te deberia aparecer un zik.sh en el $PWD.
  > ls
  > bash zik.sh


P99: Proponer ideas
  El ciclo acabado, se puede proponer mejoras al usuario pero esperar su opinión, antes de implementarlas
  - Subir a una pagina web
  - Permitir al usuario entrar ecuaciones
    - Con dialog o url (si en pagina web)
    - Guardar las nuevas ecuaciones: en archivo o coookie (si web)
  - Mas botones|teclas: q para salir, m para volver al menu
  - Interfase visual que muestra las "notas" que están corriendo

  Una vez el usuario valido una mejoras, se empieza un nuevo ciclo ágil de desarrollo


End:
  Felicitación, ahora puedes escuchar y componer música en tu celular sin necesidad de tener acceso a la red!
  Ademas, tienes todo las herramientas y la metodología para mejorarlo.

  Hemos visto:
    - Para ejecutar un script bash, lo puedes correr como 1/ bash script.sh 2/ ./script.sh 3/ script.sh  # si su directorio esta en $PATH 4/ source script.sh

  Esta noche veremos: Herramientas del Desarrollador operacional: Contenedores y Synchronizadores => Docker y Git.
  



linux61
-------
System: Heramientas: Docker y Git



Hoy vamos a ver una herramientas de Linux útiles para los DevOps (Desarrolladores operacionales) y los administradores de sistema.

Primero vamos a ver los contenedores (ex: Docker): es fácil, solo es poner una caja alrededor de un proceso.

Después vamos a estudiar los controlo dadores de versiones (ex: Git): es difícil, casi una ciencia. Manejan cambios (Guardar, Sincronizar, Mover).



+=================+
| Parte 1: Docker |
+=================+

El Sistema de contenerizacion es viejo y sencillo.
Pero vamos a pasar un poco de tiempo sobre ese porque describe bien los recursos que usa un proceso y un proceso es un ladrillo fundamental de u sistema operativo.
Empezamos (1979) limitando el sistema de archivo y acabamos (2013) separando dos núcleos en la misma maquina. Lo mas divertido es que el segundo (2013) es mas fácil que el primero.


P01: Chroot, Namespace Jail, Sandbox, Docker, Virtual Machine
  Todo estos mecanismos restringen un proceso:

  Chroot (1979): Cambia la carpeta raíz, un proceso no puede salir de su carpeta raíz

  Namespace Jail (2000): Cambia el espacio de nombres (Archivos, procesos, socket). No ha sido muy usado.

  Sandbox (2010): O Arenero. Este termino genérico se podría referir a todo estos mecanismos.
    Pero se usa hoy (2020) para referirse al mecanismo que usa Firefox para aislar los diferentes sitio web para que una publicidad no pueda espiar tu banco.
    Firefox crea un proceso que pre-carga lo que puede necesitar para interpretar HTML.
    Después esta carga, este proceso se saca permisos de forma permanente. Es decir que ya no podrá cargar ninguna biblioteca (.so en Linux), leer ningún archivo.
    Ahora si, el proceso recibe la pagina web y ejecutara su código JavaScript en un entorno aislado

  Docker (2013): Comparte el núcleo con el sistema operativo huésped pero nada mas.
    Lo mejor que tiene Docker es que sea fácil de usar, en linea de comando (CLI) y que es mas liviano que una maquina virtual.
    En la nube se usan ambos: Docker en maquinas virtuales

  Virtual Machine (1966): Simula componentes de una machina (CPU, RAM, HD). En esta machina virtual puede correr otros programas (ex: VirtualBox, Java Virtual Machine).
    No confundir con un interpretador aunque sea parecido, el interpretador lee código tal como el humano lo escribe y la maquina virtual corre código compilado.
    En mejor ejemplo esta en el sistema Android donde un núcleo Linux corre maquinas virtuales Java (JVM por Java Virtual Machine) que corre aplicaciones. Así cada aplicación es separada de forma optima.


P02: Cambio de raíz: Chroot
  El comando "> chroot" (para CHange ROOT) permite cambiar la raíz (el "/" del comando "> ls /".
  Con esta tecnología, en 1991, se creo el primer tarro de miel ("honeypot") para estudiar los virus. El nombre "honeypot" aparecerá muy poco tiempo después, con Internet (1991 también) porque sirve para atraer virus como la miel atrae los gusanos.
  Hoy, en 2020, os tarros de miel, están pasando de moda, porque son trampas demasiado obvias. Ahora hablamos de la "Tecnología del engaño" (Software decepcion technology).

  Para este ejemplo mínimo, usaremos un binario sin dependencia, así no buscara otros archivos al correr y no hay que copiar todo un árbol de dependencia.
  Usaremos la BusyBox caja del ocupado que contiene la lista de los comandos Unix (ver Wikipedia)
  
  # Instala el binario
  sudo apt install busybox-static

  # Averigua que esta bien independiente
  ldd $(which busybox)
  # OUTPUTS: not a dynamic executable
  # Lo que significa que es estatico
  # Nota que (> ldd) significa "List Dynamic Dependencies\"

  # Copia el ejecutable busybox en el direcotrio que vas a usar para chroot
  mkdir ~/Test/Chroot
  cd ~/Test/Chroot
  cp $(which busybox) .

  # Ejecuta "sh" de "busybox" en el entorno con raiz cambiada con el usario "jim"
  PS1='chroot.\h:\w\n$ ' sudo chroot --userspec=jim:jim . ./busybox sh
  # Cambie PS1 (el prompt) para este commando
  # -- porque el que esta configurado en tu maquina se refiere a funciones bash

  # Juega en el entorno chrooteado
  pwd
  PATH=/:$PATH
  busybox
  busybox ls
  busybox echo "A new File Created in Chroot Env" > file_from_chroot.txt
  busybox ls
  busybox cat file_from_chroot.txt

  # Observa las limitaciones del cambio de raiz
  busybox ls -di /    # Mira el numero del inode, si no es 2, estas en un chroot
  busybox ps -al      # No puedes listear ni los procesos del chroot, porque falta /proc
  busybox ip address  # Pero si puedes ver la red real
  busybox whoami      # No puedes saber quien eres
  busybox hostname    # Pero si puedes saber el nombre real de la maquina

  # Sal del entorno chrooteado
  exit

  # Mira que se creo el archivo en el directorio real
  pwd
  ls
  cat file_from_chroot.txt
  busybox ls -di /  # Mira que el numero del inode es 2, lo que te dice que no estas en un entorno chrooteado


P03: Carcel de espacio de nombres (Namespace Jail)
  Como recién hemos visto, el problema de cambio de raíz es que solo aisla el sistema de archivos.
  Para aumentar el nivel de aislo, Berkley Software Distribution (BSD) ha creado una cárcel de espacio de nombres (Namespace Jail).

  Los espacios de nombres son como prefijos a los nombres.
  En un sistema, pueden aplicarse a:
  1. Sistema de archivos (filesystem). Lo mismo que hace el chroot: remplaza ~/Test/Chroot por /
  2. Identificadores de Procesos (PID),
  3. Identificar de red (network stack usado por los sockets)
  4. Usuarios y grupos (UID y GID)
  5. Nombre del huesped (hostname)
  6. Memoria de acceso aleatorio RAM. Se puede aislar la memoria compartida que usan las comunicaciones ínter procesos.

  La cárcel de espacio de nombres permite aislar todo eso.
  Como te puedes imaginar es complicado (y hoy inútil) de usar => no lo vamos a hacer!


P04: Arenero (Sandbox)
  La cárcel es mucho trabajo para digamos una pagina web.
  Para una sola aplicación, existe el Arenero.
  Para usarlo de forma programática, puede ser un poco complicado porque hay que cargar todo los recursos antes de aislarse.
  Pero existe un utilitario para correr en un Shell
  
  # Instala firejail
  sudo apt install firejail

  # Corre firejail
  firejail  --whitelist=~/Test/Chroot bash

  # Observa
  pwd
  ls ~
  whoami
  ps -aux
  ip


P05 Docker: lo nuevo
  Docker ha sido creado en 2013 por dotCloud, Inc.
  Y hoy día es muy popular.
  Su gran ventaja es la facilidad del uso (como lo vamos a ver).
  Un contenedor Docker es mucho mas liviano que una maquina virtual porque comparte el núcleo con el huésped.
  Pero obviamente, no se puede reconfigurar este núcleo dentro de un contenedor Docker


P06: Docker: Introducción
  # Instala docker
  sudo apt install docker

  # Corre tu primer docker
  docker run hello-world

  # Observa
  docker images

  # Otro
  docker run docker/whalesay cowsay Hello there!

P07: Docker: primer Dockerfile
  # Crea un archivo que describe la configuracion y el contenido del contenedor
  nano Dockerfile
  # Escribe lo siguiente:
  # -->
  # FROM debian:stretch
  #
  # RUN apt-get update && apt-get install -y cowsay fortune
  # <--

  # Genera una "Imagen" docker usando la desciption de este DOckerfile
  docker build -t jim/cowsay-dockerfile .

  # Averigua que la imagen ha sido creada
  docker images

  # Corre la imagen, creando un contenedor que desaparece al salir
  docker run jim/cowsay-dockerfile /usr/games/cowsay "Hi!"


P08: Docker: Imágenes, Contenedores
  # Observa
  docker images
  docker ps -a

   # En otra terminal
  docker run -it --name=jim_cowsay_container jim/cowsay-dockerfile  bash
  # -it para InTeractive
  # Le damos un nombre para connectarse, sino docker le da uno por defecto

  # Observa

  # En otra terminal
  docker exec -it jim_cowsay_container bash

  # Intenta conversar entre las dos terminal
  # Si puede, es un oyo de seguridad?

  # Observa


P09: Docker: Ciclo de vida
  > firefox https://medium.com/@BeNitinAgarwal/lifecycle-of-docker-container-d2da9f85959
  pause
  unpause
  start
  stop
  kill
  rm



+==============+
| Parte 2: Git |
+==============+

P11: Git: y Github
  Git es el controlador de versión.
  Creado en 2005 por Linus Torvalds el creador de Linux para controlar las versiones del código del núcleo de Linux.
  Existen otros controladores de versión: Mercurial, Svn, BitKeeper pero Git la lleva!

  Github es un sitio web: https://github.com
  Ha sido comprado por Microsoft en 2018.
  Los servidores de Github alojan servicios Git, por lo tanto, permite respaldar y compartir código. Es muy conocido en el mundo de fuente abierta, sobre todo por ser uno de los primeros y tener bonita interfase html (GUI)
  Ahora tiene también una interfase CLI que se llama Github CLI.

  Existen otros servidores que alojan servicios Git: Bitbucket es mas barato y con mejor interfase en gestión de boleto => Alma lo usa. Gitlab, que se puede alojar en su propia machina y es el primero que podía alojar código privado de forma gratuita => Lo use par preparar presentaciones con colegas sin que nadie vea lo malo de nuestro flujo de trabajo. SourceForge tiene una interfase mas intuitiva que Github, puede importar proyectos enteros de este ultimo.

  Google y Microsoft alojan su código en Github.

  Usa Firefox para crear una cuenta en https://github.com


P12: Git: Primer repo
  -> Crea un repositorio en github.com
  -> Llamalo byte_gui
  Github te muestra una pagina quick setup. Leela!
  Nota que Git (CLI) y Github (GUI) suelen aconsejarte en función del momento en que estas.
  Si no has leído estos consejos 10 veces, es bueno seguir leyéndolos.

  En este caso, vamos a seguir: "create a new repository on the command line" ...
  -- Porque todavía no tenemos ningún proyecto local.
  -- En ~/Software/ByteGui



P13: Git: Ciclo de vida
  # 1/ Descarga la siguiente hoja de trucos Git
  wget https://www.jrebel.com/system/files/git-cheat-sheet.pdf

  # 2/ Abrela
  xdg-open git-cheat-sheet.pdf

  # 3/ Y markdown
  firefox https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
  Hablemos de:
  1/ Add, Commit
  2/ Push
  3/ Pull
  4/ Markdown format: tu primer idioma de Markup


P14: Git: Primer Push, un poco de Markdown
  # 3/ Mueve el escript de la clase anterio en tu proyecto git
  cd ~/Software/ByteGui    # Para trabajaar con git, necesitas tener en working directory en el repo
                           # Suena logico, tienes que estar en el repo para que tus commandos afecten este repo
  mv ~/Test/zik.sh .       # "." significa "aqui" (en el PWD)

  # 4/ Escribe un poco el README.md
  # -- Nota que pongo emfafis en la documentacion,
  # -- que debes escribir y compartir antes que el codigo
  # -- Eso permite ordenar y syncronisar las ideas
  # -- Ver cyclo de desarollo de programa => no precipitarse en el codigo
  nano README.md  # Nota la extencion md para markdown

  # -- agrega el titulo "# ByteGui: CLI para leer ByteBeat"
  # -- (Nota que empieza con "#" un titulo segun el formato markdown)

  # -- Agrega las caracteristicas del proyecto ("features")
  # -- corre "jim class062 head -n 50" y escribes, en ingles los requerimientos como una lista:
  # -- 1. req1
  # -- 2. req 2 (Nota que las lineas empiezan con "1. " que es lista numerotada)

  # -- Agrega los enlaces (despues de un subtitulo "## Links") que encontraras en:
  cat $(which jim)/lib/class/README.md

  # 5/ Agrega las modificaciones de los archivos al "Stagin area"
  # -- Es decir lo que se va a guardar al proximo commit (=instantaneo)
  git add .

  # 6/ Haga la captura instantanea
  git commit -m "Add zik.sh and README.md"  # Lo que esta en doble cita es el mensaje del instantaneo (que ahora llamaremos "commit")

  # 7/ Empuja tus cambios al servidor
  git push

  # 8/ Verifica en tu pagina si los cambios son visibles


P15: Git: Ramas (Branch)
  Queremos jugar sin contaminar el código de los demás

  # Crear una rama, lamada \"dev\"
  cd ~/Software/ByteGui
  git branch dev

  # Cambiar de rama
  git checkout dev

  # Commitear cambios
  cat 'Git is awesome' > file_to_delete.txt
  git add . && git commit -m 'First dev uselesss commit'

  # Observar
  gitk

  Porque las Ramas? Es solo para "jugar" es decir hacer pruebas?
  Es realidad las ramas permiten trabajar de su lado, haciendo cambios útiles para el futuro pero que todavía no importan a los femas.
  Cuando la rama personal esta lista, se puede unir a la común.
  Asimismo, se dibujo una hierarquía en unos proyectos: Rama mía < rama comunal < rama regional < rama nacional < rama internacional


P16: Git: Introspección

  # Clonea un repositorio (= descargar por primera vez)
  cd Test
  git clone https://github.com/vimwiki/vimwiki Vimwiki; cd Vimwiki

  # Muestra como estamo
  git status

  # Interfase graphica
  gitk --all

  # Muestra las differencias entre el working direcotry Vs Staging area
  echo "This file have been modified" >> README.md
  git diff

  # Remueve las modificaciones
  # git checkout -- README.md  # Eso uso pero te la remove sin devolucion

  # Remueve las modificaciones (con respaldo)
  git stash && git stash pop

  # Mira quien introdujo tal linea => quien tiene la culpa
  git blame README.md


P17: Git: Unir y rebasar (Merge y Rebase)

  cd ~/Software/ByteGui

  # Crea la rama dev1 y anda ahi
  git checkout -b dev1

  # Haga cambio en common.txt (probablemente nuevo)
  echo some changes in dev1 >> common.txt
  git add . && git commit -m 'Changes in dev1'

  # Crea la rama dev2 y anda ahi
  git checkout -b dev2

  # Haga cambio en common.txt (probablemente nuevo)
  echo some changes in dev2 >> common.txt
  git add . && git commit -m 'Changes in dev2'

  # Hagale un repaldo
  git branch dev2_bck

  # Une dev1
  git merge dev1

  # Sigue las instrucitones de git para resolver los conflictos editando archivos

  Este ejercicio se puede hacer:
    1. Usando rebase mientras que merge
    2. Haciendo múltiples commits
    3. Editando distintos archivos (Pero si no hay conflicto, es fácil)


P18: Git: Remover cambios
  El (sub)comando "> rebase -i" permite reescribir la historia.
  Aquí, vamos solo a borrar las ramas que no nos importan.

  # Anda a la rama maestra
  git checkout master

  # Muestra las ramas
  git branch

  # Bora las ramas malas
  git branch -D dev1

  Nota que una vez hecho un commit en git, aunque lo borres queda un copia local durante unos meses así que sin miedo.
  Eso si el > git checkout -- .  o el > git clean borran todo los cambios locales sin commitearlos.
  Por lo tanto se pierden hasta siempre.


P19: Git: Mantenimiento avanzado
  Jugamos en un proyecto real que mantengo Vimwiki
  Donde arregle código bueno pero git malo de un contribuidor.
  Vamos a repetir estos paso codo a codo, te tinca?

  https://github.com/vimwiki/vimwiki/pulls?q=jeromg+type%3Apr


End:
  Felicitacion, son dos piedras mas en tu bolisilo, no olvides celebrar cada victoria.

  Hemos visto:
  > chroot: Commando unix para cambiar el directorio raiz, y asi aislar
  > docker: El programa de contenedores
  > git: El programa de gestion de version

  Tags: > nano
  



linux62
-------
-- Tarea: Heramientas: wget, curl, chroot, docker, git

  # Define una variable para ayudar
  chr=~/Test/Chroot

  # Cambia el repertorio corriente
  cd $chr

  # Copia los ejecutable que queremos (-v = verbose)
  cp -v /bin/{bash,touch,ls,rm,cat} $chr

  # Muestra las dependencias dynamicas de bash
  ldd $(which bash)

  # Pon la lista de archivos de dependecias en una variables
  lib="$(ldd $(which bash) | egrep -o '/lib.*\.[0-9]')"

  # A ver ...
  echo $lib

  # Copia las dependenciaso
  # -- adminra el --parents que copia los direcotios padres al mismo tiempo
  for i in $lib; do cp -v --parents "$i" "${chr}"; done

  # De la misma forma, copia las dependencias dynamicas de:
  # -- touch, ls, rm, cat
  # -- Es decir remplazar /bin/bash en la definicino de lib por los siguiente
  # -- y repite el comando que copia en un ciclo

  # Entra el el chroot
  # -- El comando es largo porque cambia:
  # -- -- PS1 (el prompt)
  # -- -- PATH (la lista de camino donde BaSh busca los ejecutables)
  # -- -- El usario
  PS1='chroot.\h:\w\n$ ' sudo chroot --userspec=jim:jim  . ./bash -i -c 'export PATH+=/:; export PS1; exec $BASH'

  # Juega
  help  # Comando interno a BaSh ("Builtin")
  ls
  ls -di /
  echo 'In new file' > new_file.txt
  ls
  exit
  ls


P02: Unshare
  Es una llamada sistema con un comando del mismo nombre.
  Muy nuevo (2013) y desconocido, sirve para aislar un espacio de nombre (i.e. crear un arenero).

  # Aisla el espacio de nombre de los procesos
  sudo unshare --fork --pid --mount-proc

  # Averigua
  ps -aux

  # Sal
  exit


P03: Wget
  Hablando de herramientas:
  Wget sirve para descarga paginas o sitio del www.
  Los ejercicios que siguen quizás se demoran un poco y chupan mucha conmoción => no dudes en Ctrl-C después de la segunda pagina descargada.


  # Technica para pner comentarios sobre os argumentos
  # -- Define el commando como una cuadra
  cmd=(wget
    # Indica el nombre de la salida con -o (-O para mas mesajes)
    -O taglist.zip
    # Limita el ancho de bando
    --limit-rate=200k
    # Reinicia si la ultima descarga no ha sido completa
    -c
    # Re-intenta 75 veces si falla
    --tries=75
    # Selectiona user-agent (la identidad del navegador)
    # -- nota las citas simples o La evaluacion separara lo que sigue
    # -- en distintos argumentos (word splitting)
    '--user-agent="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092416 Firefox/3.0.3"'
     # URL de la pagina: por fin
     http://www.vim.org/scripts/download_script.php?src_id=7701
  )

  # Ejectua el commando <= Array interpolation
  # -- <= me demore 10 anios para ya no asustarme de las cuadras en BaSh
  "${cmd[$@]}"
  ls

  # Descarga todo lo que encuentra con ese URL en prefijo
  # -- El problema es que suele no encontrar mucho (ver despues)
  wget --recursive -c -N  --no-parent -nH  -P BashWiki https://wiki.bash-hackers.org/syntax/
  # Ctrl_c rapdio
  find BashWiki

  # Descarga todo esta pagina y los enlaces de esta pagina
  # -- con un limite de recursion de 2
  # -- aun asi, suele descargar todo internet
  # -- por lo tanto, lo limite al dominio que apunto
  wget --recursive  --domains=wiki.bash-hackers.org -P BashWiki -H -l 2 https://wiki.bash-hackers.org/syntax/basicgrammar
  # Ctrl_c rapdio
  find BashWiki

  # Descarga un sitio completo
  # -- El comando precendente, finalmente iba a descargar todo el sitio
  # -- Lo que se hace asi:
  wget --mirror -p --convert-links -P BashWiki https://wiki.bash-hackers.org/
  # Ctrl_c rapdio
  find BashWiki

  Anota también las opciones:
  -i list.txt = Descarga desde la lista presente en el archivo list.txt
  -e robots=off = ignora robots.txt, un archivo que ayuda los robots como wget
  --no-check-certificate --content-disposition = no se pero permite descargar de github

  Para saber mas, StackOverflow es tu amigo.


P04: Curl
  Curl, es la herramienta para hacer solicitudes HyperText Transfer Protocol (HTTP).
  Por defecto, Curl manda la solicitud POST. Pero existe otras.
  Aquí los distintos métodos HTTP copiados desde "Mozilla Developer Center" la referencia sobre las tecnologías de Internet: https://developer.mozilla.org/es/docs/Web/HTTP/Methods


  |-----------+-------------------------------------------------------------------|
  | Solicitud | Descripcion                                                       |
  |-----------+-------------------------------------------------------------------|
  | GET       | El método GET solicita una representación de un                   |
  |           | recurso específico. Las peticiones que usan el método             |
  |           | GET sólo deben recuperar datos.                                   |
  |-----------+-------------------------------------------------------------------|
  | HEAD      | El método HEAD pide una respuesta idéntica a la de una            |
  |           | petición GET, pero sin el cuerpo de la respuesta.                 |
  |-----------+-------------------------------------------------------------------|
  | POST      | El método POST se utiliza para enviar una entidad a un recurso    |
  |           | en específico, causando a menudo un cambio en el estado o efectos |
  |           | secundarios en el servidor.                                       |
  |-----------+-------------------------------------------------------------------|
  | PUT       | El modo PUT reemplaza todas las representaciones actuales         |
  |           | del recurso de destino con la carga útil de la petición.          |
  |-----------+-------------------------------------------------------------------|
  | DELETE    | El método DELETE borra un recurso en específico.                  |
  |-----------+-------------------------------------------------------------------|
  | CONNECT   | El método CONNECT establece un túnel hacia el servidor            |
  |           | identificado por el recurso.                                      |
  |-----------+-------------------------------------------------------------------|
  | OPTIONS   | El método OPTIONS es utilizado para describir las opciones        |
  |           | de comunicación para el recurso de destino.                       |
  |-----------+-------------------------------------------------------------------|
  | TRACE     | El método TRACE  realiza una prueba de bucle de retorno de        |
  |           | mensaje a lo largo de la ruta al recurso de destino.              |
  |-----------+-------------------------------------------------------------------|
  | PATCH     | El método PATCH  es utilizado para aplicar modificaciones         |
  |           | parciales a un recurso.                                           |
  |-----------+-------------------------------------------------------------------|


  # Obtener una pagina web (Aqui la meteo de tu lugar y la ayuda de esta REST API)
  # -- GET: como (yo) obtener esta pagina: Osea (tu) dame esta pagina
  # -- Nota que los metodos HTTP toma el que los manda como subjecto
  curl http://www.wttr.in?n
  curl http://www.wttr.in/:help

  # Hacer multiples solicitudes de una (-s)
  curl -s 'wttr.in/{Santiago,Rancagua,Paris,Cherbourg}?format=3'

  # Especificar tus credenciales
  curl -u username:password -d status='curl is great' http://twitter.com/statuses/update.xml

  # Elejir el protocolo IP (IPv4 o IPv6): Obtener tu IPv4
  curl -4 icanhazip.com  

  # Para seguir, necesitamos un servicio: no encontre en la red uno que hacia solo un log de
  # -- las solicitudes. Instala netcat, el cuchillio Suisso de la red
  # -- (no confundir con netstat que es mucho mas basico)
  sudo apt install netcat

  # En otra terminal (El servidor)
  # Escucha (-l listen) el puerto (-p port) 8080
  # -- y quedate vivo aun al fin de la connection (-k keep-alive)
  nc -l -p 8080 -k

  # NetCat Aprueba !
  # Ahora si !
  # En otro terminal, manda los commandos que siguen

  # PUT: Manda datos
  # -- Mira lo que recibe el servicio
  # -X : --request
  # -m : --max-time (no esperar la repuesta, por defecto hay que apretar Ctrl-C para acabar)
  # -d : --datos
  curl -X PUT -m 0.1 -d arg=val -d arg2=val2 localhost:8080

  # PUT: en formato Json
  # -- Json es mas facil generar, ya que acepta datos con nevo linea, espacio ...
  # -- Es el formato de dato de internet <= (JavaScript Object Notation)
  # -H : --header
  curl -X PUT -m 0.1 -H "Content-Type: application/json" -d '{"name":"mkyong","email":"abc@gmail.com"}'

  # POST: Quasi Lo mismo
  # -- PUT es "idempotent: es decir que hacer 2 veces PUT es como hacerlo 1 vez
  # -- POST no lo es, puedes mandar 2 correos, iguales va a recibir 2 (el medio spam)
  # -- Eso dichos, HTTP no tiene nada que ver con os email que usan los protocolos:
  # -- IMAP, POP3, SMTP (muy complicado, afuera del rango de esta clase)
  curl -d "param1=value1&param2=value2" -X POST localhost:8080

  # POST: un archivo
  # -- 1/ Escribelo
  echo "Si estamos en HTTPS (y no HTTP), solo tu (servidor) y yo (cliente) podemos leer eso" > data.txt
  # -- 2/ Mandalo
  # -- -- @ : Leer at
  curl -X POST -d "@data.txt" localhost:8080
  Ese ultimo se lee:
  En HTTP (curl), con el protocolo (-X) "POST" manda los datos (-d) en el archivo (@) data.txt al servicio
  -- escuchando en el puerto 8080 de este computador "localhost" (para huésped local)
  Expresivo ! O no ?


P05: Docker
  Ese: https://docs.docker.com/get-started/
  Es la documentación oficial de Docker como lo puedes ver al URL (Universal Resource Locator) (alias: Enlace)
  Sigue la 3 partes de "QuickStart"


P06: Git
  Ese: https://learngitbranching.js.org/
  Es uno de los 42.000 recursos para aprender Git.
  Este es totalmente el linea.
  Haga los 4 primeros ejercicios (Ramping Up)


End:
  Felicitación
  Esa era la clase la mas pesada: herramientas complicadas.
  Y, por primera vez, trabajaste en autonomía.

  Eres listo para ir solo por las calles! Todavía no!
  Osea si pero, un poco de teoría te reforzara => me gustaría retenerte para las 3 mejores clases:
  8. Programación genérica
  9. Servicios y Servidores
  10. Zoologico de los idioma de programacion

  Tag: > nc > netcat
  



linux71
-------
Syntax: Language: Funcion, Rama, Ciclo y Regex


+==========+
| Lenguaje |
+==========+

Escribir lenguajes informáticos es el trabajo de los desarrolladores.
No es (para nada) la parte mas difícil de la informática. Al contrario.
Es el principio. Empezaste tu estudios con eso y yo también.
Tal como un niño empieza su vida intelectual aprendiendo a hablar pero al crecer, puede estudiar literatura hasta los 80 años (y mas).
En todo caso, si no sabe hablar, esta cagado!

Un idioma informático es muy básico. Tiene 50 palabras en 5..10 grupos lexicales (nombre, verbo, adjetivo) distintos. Aquí son: comando, argumento, variable, controlador, comentario, operador.

BaSh no es el lenguaje el mas fácil, pero si el mas accesible, rápido de llamar ya que es el lenguaje por defecto del Shell Linux.

P01: Un ejemplo gramatical
  > if [[ 1 == 1 ]]; then let a=42; else let a=31; fi; echo $a  # Que pasa
    ^- controlador         ^- comando        ^- variable        ^- comentario
            ^- operador                          argumento -^


P02: Ciclo
  Hay distintas formas de hacer un ciclo, iterar sobre una lista o repetir una tarea cambiando un contador hasta que una cierta condición ya no sea valida.
  Empezamos con la lista. La generamos con interpolación de rango "{1..10}"

  # Experimenta la expancion de rango
  echo {1..10}

  # Tu primer cyclo
  for i in {1..10}; do
    echo "La variable llamada \"i\" tiene el valor $i"
  done

  # Lo mismo en una linea
  for i in {1..10}; do echo $i; done

  Bastante fácil no?
  El mismo ciclo con sintaxis tipo C
  Observa las dobles paréntesis que hacen pensar en una interpolación aritmética

  for ((i=1; i<=10; i=i+1)); do
    echo "i = $i";
  done

  El mismo ciclo con el ciclo "Mientras"

  i=1
  while ((i<=10)); do
    echo "i = $i"
    ((i++))
  done

  Un poco sobre el valor de retorno de las operaciones:
  Nota que $? es una variable que tiene el valor de retorno del comando anterior

  cat this_will_fails_because_file_do_not_exists; echo $?

  echo "this will succeed"; echo $?

  true; echo $?

  false; echo $?

  # Cyclo infinito
  while true; do
    echo "Stop me with a signal (Ctrl-C)"
  done

  # Cabros esto no prendió
  echo "Antes del cyclo"
  while false; do
    echo "En el cyclo"
  done
  echo "Despues del cyclo"


P03: Condición
  Cuando un quiere ejecutar código solo en ciertos casos.
  La forma canónica es ejecutar un bloque si un comando tiene éxito


  # Crea el archivo "present.txt"
  touch present.txt

  # Prueba el sabor del exito
  cat present.txt > /dev/null; echo $?

  # Prueba el sabor del fracaso
  cat not_present.txt > /dev/null; echo $?

  # Pero que aburido esta linea del StdErr, redirigala al StdOut
  # -- que el mismo esta redirigido al agujero negero
  cat not_present.txt > /dev/null 2&>1; echo $?

  # Ahora si podemos probar si un archivo existe => if; then; fi
  if cat present.txt > /dev/null 2>&1; then
    echo "File is present"
  fi

  # Y sino => if; then; else; fi
  if cat not_present.txt > /dev/null 2>&1; then
    echo "File is present"
  else
    echo "File is NOT present"
  fi

  Con esto, ya puedes hacer todo lo que quieres con las condiciones.
  Nota que el "comando" puede ser también una función.
  Pero puede ser lento crear un comando o llamar una función para solo probar:
  - si un archivo existe
  - si dos strings son iguales
  - si un numero es inferior a otro

  Por eso, vamos a recurrir a protocolos internos de BaSh, que, como siempre, llamamos "interpolaciones".

  # Interpolacion de prueba con opciones hereradas de la historia
  # -- -f = si el archivo existe
  if [[ -f present.txt ]]; then echo "File is present"; fi
  # -- ! = invierte la condicion
  if [[ ! -f not_present.txt ]]; then echo "File is not present"; fi

  # Interpolacion de prueba para igualda
  var="value"
  if [[ "$var" == "value" ]]; then echo YES; else echo NO; fi
  if [[ "$var" == "not_value" ]]; then echo YES; else echo NO; fi

  # Interpolacion arithmetica => tambien tiene un valor de retorno
  for i in {1..10}; do
    if ((i<=10/2)); then
      echo "$i is small"
    else
      echo "$i is big"
    fi
  done

  Un error frecuente es olvidar de cerrar el bloque: con "done", "fi" o "}" para respectivamente los ciclos, condiciones y funciones.
  Que pasa si no lo pones?

  Una otra palabra clase de condición es "elif"

  var=4
  if ((var==2)); then
    echo two
  elif ((var==3)); then
    echo three
  elif ((var==4)); then
    echo four
  else
    echo other
  fi

  Pero a veces puede ser feo de leer porque al final eso es un interruptor con distintos casos. Por lo tanto, lo que sigue, en C, se llama un "switch" o interruptor

  var=4
  case $var in
    2)
      echo two
      ;;

    3)
      echo three
      ;;

    4)
      echo four
      ;;

    *)
      echo other;
      ;;
  esac


P04: Funciones
  Antes de 1945 todo lo que precede se hacia con saltos condicionales e incondicionales.
  El código era naturalmente espagueti.
  La invención de las subrutinas (hoy día llamada funciones) era simple, crear bloques de código llamados, así el llamador llama el código por su nombre y sabe que el código va a volver con una repuesta.
  Nota: Antes no se sabia si un salto iba volver => ver en C "longjmp" que todavía se usa en la terminal al hacer un comando porque a veces no vuelve, por ejemplo "exec").

  Asi que los "CALL" remplazaron unos "JUMP".
  En BaSh:

  # Declarar funciones
  hablar(){
    echo "Esta funcion se llama hablar"
  }
  decir(){ echo "Esta funcion dice $1"; }
  blabla(){ echo "Esta funcion blabla $@"; }

  # Llamar las funciones
  hablar "Este ni escucha sus argumentos"
  decir "Hola Jaime" "No escucha al segundo"
  blabla "Este" "esta repitiendo" todo los argumentos

  Nota 1:
  - La variable $1 se refiere al primer argumento, $2 al segundo, etc hasta el $9.
  - La variable $@ es una tabla con todo los argumentos.

  Nota 2:
  Edsger Dijkstra (1930 - 2002) formulo el patrón de la entrada única y salida única de una función.
  Eso es lo que llevo a definir las funciones como las conocemos hoy día: la llamas a su entrada y el flujo de control vuelve a ti, una vez la función ejecutada.
  Este patrón ahora es muy mal interpretado. Por ejemplo la gente viene a pensar que una función puede tener solo una palabra clave "return", cuando, al contrario, salida temprana es recomendada en caso de error o de no necesidad de trabajo por ejemplo.
  Acuérdate que el patrón "Single Entry, Single Exit" es lo que define una función y lo usan todo los idiomas modernos (después de Fortran 1966) y en ningún caso un prohibicion de salir al toque.


P05: Alan Turing (1912 - 1954)
  Es el padre de los informáticos transformo las matemáticas de la computación en la informática que, como sabes, hoy día es un ciencia aparte,
  La informática es mas cerca de la matemáticas que cualquier otra ciencia por la única razón que es la ultima que se separo (digamos en 1955).
  Por la misma razón Galileo Galilei (1564 - 1642) es el padre de los físicos.

  Quisiera comentar 2 cosas (de sus trabajos): el problema de la parada y la maquina de Turing

  5.1 Problema de la parada (1936)
  "En el caso general, es imposible saber si un programar va a llegar a su salida o no" y un corolario inmediato, no se puede saber si va a ejecutar una cierta rama, y el segundo corolario, es imposible estar seguro de lo que va a hacer. Entiende bien que hablamos de un caso general y no de programas particulares, que a 99% se puede leer y predecir.
  Este theorema de la parada de Turing (1936) es un correlario de los teoremas de incompletitud de Gödel (1931) que stipula que "Cualquier teoría aritmética recursiva que sea consistente es incompleta".
  Ambas pruebas recursivamente absurdas, Turing copio Godel hasta en la prueba. Aqui esta la de Turing en Python:

  # Prueba del theorema de la parada (fuente Wikipedia)
  def termina(p):
      # Supongamos que aquí se encuentra un código maravilloso que soluciona el problema de la parada
      # Esta función regresa True si el programa p termina o False en otro caso

  # Funcion principal recursivamente absurda
  def main():
      if termina(main):
          ciclo_eterno()  # while True: pass  # en Python

  # LLama la funcion principal
  main

  En castellano, si podemos saber que un programa termina o no, se puede construir un programa que si termina, no termina y si no termina, termina.
  Lo que es absurdo => no se puede saber de forma genérica si un programa termina, osea la función "termina" nunca se podrá escribir.

  Nota que esta absurdidad venida de Gödel revoluciono las matemáticas también.
  Conclusión 2: Lo que se puede entender y formular bien gana sobre lo incomprehensible


  5.2 Maquina de Turing (1936)
  Una maquina de Turing tiene 2 operaciones llamada transiciones:
  1. Mover a la derecha
  2. Mover a la izquierda

  Tiene un estado interno (variables), un alfabeto (sintaxis) y un código de entrada
  Así se representa:


Input:
01
┌─────────────┬─────────┬──────────┬─────────────┬─────────────┐
 STATE: q0   │ READ: 0 │ WRITE: o │ GO TO: qo1  │ MOVE: RIGHT │
└─────────────┴─────────┴──────────┴─────────────┴─────────────┘
╔═▼═╗───┬───┬────
 0 ║ 1 │ B │ ···
╚═▲═╝───┴───┴────

┌─────────────┬─────────┬──────────┬─────────────┬─────────────┐
 STATE: qo1  │ READ: 1 │ WRITE: i │ GO TO: qrb  │ MOVE: RIGHT │
└─────────────┴─────────┴──────────┴─────────────┴─────────────┘
┌───╔═▼═╗───┬────
 o ║ 1 ║ B │ ···
└───╚═▲═╝───┴────

┌─────────────┬─────────┬──────────┬─────────────┬─────────────┐
 STATE: qrb  │ READ: B │ WRITE:   │ GO TO: qa   │ MOVE:       │
└─────────────┴─────────┴──────────┴─────────────┴─────────────┘
┌───┬───╔═▼═╗────
 o │ i ║ B ║ ···
└───┴───╚═▲═╝────

  Se puede demostrar que es posible construir una máquina especial de este tipo que pueda realizar el trabajo de todas las demás. Esta máquina especial puede ser denominada máquina universal.
  Unos 15 años después nace la informática (1950), el transistor también ayudo <= física cuántica de ... también 1936! Y 20 anos después (1969), el humano pisa la luna.
  Tienes que entender que la machina de Turing no es una vieja maquina pasada, es un modelo matemático que representa cualquier computador y que permita a cualquier computador simular cualquier otro.



+===================+
| Expresión regular |
+===================+

Una expresión regular es una secuencia de caracteres que conforma un patrón de búsqueda.
Es como un sub-idioma.

El idioma consiste en átomos, multiplicadores y alteraciones.
Una buena referencia es:

> man perlreref

No olvides que Perl significa: "Pattern Extraction and Report Language".
Y extracción de patrones se hace mediante expresiones regulares.

Muy fácil:
  AlfaNum: Los caracteres alfa numéricos como 1, 3, s, b significan estos caracteres literales, excepto si están escapados como, \1, \3, \s,  en cual caso, toman un significado especial
  Puntuación: La puntuación como: ., ?, (, [, * tiene un significado especial excepto si están escapado como: \., \? ,\(, \[ en cual caso, tienen un significado literal


P01: Un ejemplo gramatical
  (Mira la pregunta siguiente [P02] para decargar abs.txt)

  grep -P '^(cat|echo) .*\|.*$' abs.txt

  ^  ---------  principio de linea (átomo)
  (  ---------  empezar grupo (token)
    cat  -----  "cat" literal (serie de átomos)
    |  -------  o (alteración)
    echo  ----  "echo\' literal
  )  ---------  cierra grupo
  <espacio>  -  espacio literal
  .  ---------  cualquier carácter (átomo)
  *  ---------  cualquier numero de veces (cuantificador)
  \| ---------   "|" literal
  .* ---------  cualquier carácter, cualquier numero de veces
  $  ---------  fin de linea (átomo)

  Lo que coincide (match) con:
  -- cat o echo al principio de la linea seguido por
  -- un espacio y cualquier numero de cualquier caracteres (".*") seguidos por
  -- un tubo "|" seguido por cualquier numero de cualquier caracteres (".*") seguido por
  -- el fin de la linea

  Puedes ya adivinar que ".*" se usa mucho en RegEx


P22: Descarga el libro Advanced Bash Scripting
  Ya deberías tenerlo del la clase 6:
  
  wget -qO- https://tldp.org/LDP/abs/abs-guide.txt.gz | gunzip - > abs.txt


P23: Corta el contenido del libro, principio de linea (^)
  Aquí vemos nuestra primera expresión regular en sed:
  ^Chapter => Match principio de linea ("^") seguido por literalmente "Chapter 2"
  
  cat abs.txt | sed '/^Chapter 3/ q' > ab.txt

  Sed hace para cada linea el comando pasado en parámetro.
  Aquí el comando es: si la linea coincide con el patrón entre "/", quit ("q")


P24: Estar o no estar: cuantificadores (?)
  Hay distintos dialectos de expresiones regulares.
  Vamos usar las de Perl: PCRE para Perl Compatible Regular Expression
  Por lo tanto, agregaremos la opción "-P" a grep
  Ademas para evitar que el argumento se divide o expande o interpole, lo pondremos entre simples citas

  Queremos encontrar las palabras "sh" o "bash"
  
  grep -Pi 'b?a?sh' ab.txt

  -P: Expresión regular en formato Perl
  -i: Ignore case = pude ser mayúscula o minúscula

  El patron es:
  b? = "b" o nada ("?")
  a? = "a" o nada ("?")
  sh = "sh"

  Mira la parte "SYNTAX" (opcionalmente "QUANTIFERS") del manual.
  Tienes que entender ?, * y +
  De hecho, vamos a buscar en el manual (o en Vim) con "/". En Nano aprieta f1 para obtener ayuda.


P25: Regex a átomo: agrupar (())
  El problema de la RegEx precedente es que puede coincidir con "bsh" o "ash".
  Mira que aparece "fashion" y "Subshells"
  Por eso queremos "ba" o nada, es decir tratar "ba" como un átomo.
  Eso se llamar agrupar (gruping) y se hace mediante paréntesis, como en una ecuación matemática.
  
  grep -Pi '(ba)?sh' ab.txt

  El patrón es:
  (ba)? = "ba" o nada
  sh = "sh"

  Así, si queremos coincidir con el SheBang #!/bin/bash
  
  grep -Pi '#!\/bin\/b?a?sh' ab.txt

  Nota solamente que tubo que escapar los "/" -> "\/" que tienen un significado especial (Principio y fin de regex)


  P26: Alteraciones (|)
  Con múltiples grep en un tubo, podemos filtrar exclusivamente, pero como hacemos si queremos filtrar dos patrones inclusivamente?
  Usamos la alteración, que es lo ultimo de la clase, acuérdate: Átomos, Cuantificadores y Alteraciones
  
  grep -Pi 'system|programming' ab.txt
  grep -Pi '(system|programming) l' ab.txt
  grep -Pi 'system|programming l' ab.txt

  La segunda linea imbrica la ateraciion asi que significa "system" o "programming" seguido por "l"
  Mientras que la tercera significa "system" o "programming l"


P27: Ejemplo
  Un atomo interesante para lo que sigue es "un dígito", es decir entre 0 y 9.
  Se puede escribir, de la vieja forma como "[0-9]" que significa literalmente entre 0 y nueve.
  O con Perl "\d" como Dígito, que es mas rápido de escribir
  
  # Un numero cualquier cantidad de veces (el maximo possible)
  grep -Pi '\d*' ab.txt

  # Only match (-o)
  grep -Pi -o '\d*' ab.txt

  # Ordena y cuenta
  grep -Pi -o '\d+' ab.txt | sort -n | uniq -c

  # Nota que el numbero \"36\" aparece mucho, porque
  grep -Pi '36' ab.txt

  # Hum porque es un capitulo que tiene muchas tablas
  # Si queremos saber cual tiene mas tablas
  cat ab.txt | sed -n '/List of/,/A-1./p' | grep -Pi -o '^ *\d+-' | sort -n | uniq -c | sort -n

  # Es el capitulo 16 cierto ?


End:
  Felicitación: hemos visto:

  BaSh: Los ladrillos del control de flujo en programación:
  -- Función, Rama, Ciclo

  Expresiones Regulares: Un idioma especifico al buscar patrones:
  -- Alternación, Cuantificación, Agrupación

  La tarea te hara poner la manos arriba sobre el control de flujo y las expreciones regulares
  Mañana veremos los servicios y servidores.
  Nos vemos!
  



linux72
-------
-- Tarea: Language, flujo de control y Regex


+=========================+
| Flujo de control: Tarea |
+=========================+


P01: Ir a (goto)
  Es el mas antiguo de los controladores de flujo. Herede del salto (JUMP) en Assembly.
  Se llama "goto" va directamente a la linea que sigue la etiqueta "label") dado como argumento.
  Perl y C lo soportan.
  Copia eso en goto.pl:
  -->
#!/usr/bin/env perl

use v5.25;

my $var=1;

START:
  say "start";
  goto LABEL2 if ($var == 2);
  goto LABEL1;

LABEL1:
  say "Label1";
  $var = 2 and goto START if ($var == 1);
  goto EXIT;

LABEL2:
  say "Label2";
  $var = 3;
  goto START;

EXIT:
  say "Exit";
  exit 0;
  <--

  Ejecútalo:
  > perl goto.pl

  Intenta seguir lo que esta pasando. Hay muchos saltos. Es complicado seguirlos.
  Por eso el único goto que es legítimamente aceptado en la comunidad es el
  "goto EXIT" que permite liberar los recursos antes de salir en un mismo lugar,
  antes de la salida de una función.

  Mira, por ejemplo, del núcleo Linux, este driver (de pantalla): https://github.com/torvalds/linux/blob/3650b228f83adda7e5ee532e2b90429c03f7b9ec/drivers/hid/hid-picolcd_fb.c#L568-L578
  El enlace te muestra los labels, los goto están justo arriba. Estos multiples labels de salida estan aqui para que sea mas rápido. Por eso elije el núcleo. En un caso mas general, habrá un solo label EXIT y cada liberación va a verificar si el recurso merece realmente estar liberado


P02: Ciclo
  Lo ciclos son interesante para hacer múltiples veces la misma tarea.
  Aquí un ciclo que muestra los factores de todo los enteros de 1 a 100.
  > for i in {1..100}; do factor ; done

  Haga un ciclo que crea los directorios dirXX donde XX es un numero de 1 a 99

  Siguiente ejercicio:
  -->
  # Aquí como se hace un ciclo sobre cada elemento de una table (\"array\")
  array=(first second Third fourth)
  for i in "${array[@]}"; do
    echo $i;
  done

  # Aqui como se capitaliza la primera letra de una variable
  foo=bar
  ${foo^}
  # OUTPUTS: Bar
  <--

  Haga un ciclo que pone capitaliza la primera letra de cada elemento de la cuadra de entrada y escribe el resultado en StdOut.

  Aqui encontraras cuatro
  Intenta hacer uno o dos


P03: Condición
  Las condiciones son útiles para efectuar una tarea solo en ciertos casos.
  Típicamente, si es posible o útil hacerla.
  Aqui un ejemplo usando la interpolacion arithmetica.
  Copialo en note.sh:
  -->
#!/bin/bash

# Lee la nota del usario
echo "Entra tu nota en 0 y 7:"
read -r note

# Averigua que esta en un buen formato
re='^[0-7]$'
if ! [[ $note =~ $re ]] ; then
   echo "Error: espero un numero entero etre 0 y 7 y me diste $note" >&2; exit 1
fi

if ((note >= 6)); then
  echo "Muy bien"
elif ((note == 5)); then
  echo "Bien"
else
  echo "Otro"
fi
exit 0
  <--

  Ahora ejecuta note.sh:
  > bash note.sh

  Este programa te da una apreciacion en funcion de tu nota:
  6 o mas: Muy bine
  5: Bien
  Sino: Otro

  Agrega las condiciones siguiente:
  Si la nota entregada es 4 => escribe Pasable
  Si la nota entregada es 3 => escribe Rechazado
  Si la nota entregada es inferior a 3 = (otros casos) => escribe Muy mal


P04: Función
  Enciera el codigo anterio en una function que despues llamas:
  -->
print_note(){
  # Aqui pega el codigo anterior, que lee la note y da la apreciacion
  # Remplaza los "exit" por "return"
}

# Aqui la llamas
print_note
  <--

  Y ahora la llamamos hasta que el usario de una nota valida es decir entre 0 y 7.
  Es decir que verificacion pasa y la function retorna 0 (exito en Linux)
  Remplaza la llamada print_note por esta llamada repetitiva
  -->
while true; do
  # Si print_note es existoso, sal del ciclo (break)
  if print_note; then break; fi
done
  <--

  Prueba si funciona.



+==============+
| Regex: Tarea |
+==============+

Aconsejo buscar la linea de comando por si mismo antes de leer las repuesta
Para ver las repuesta corre:
> jim class082 p11  # por ejemplo para la repuesta a la p11

P11: Regex: Fin de palabra
  Busca todos los patrones que constan de dos caracteres que terminan en "y" en /etc/passwd

P12: Regex: Alternación
  Muestra todas las líneas en /etc/passwd que contienen "root", "bin" o "sync"
  Mira bien que use la palabra o => alternación => |

P13: Regex: Agrupación
  Cuál es el resultado del siguiente comando: grep -P 'no(b|n)' /etc/passwd?
  Cuál es el efecto de usar paréntesis en esta expresión regular?
  Que pasa si las sacamos?

P14: Regex: En tubo
  Busque en las primeras 6 líneas de /etc/passwd líneas que contengan un carácter numérico
  Ayuda: las paginas manual de: perlreref, head, o sed (head es mas facil)

P15: Regex: Cuantificador exacto
  Ejecute el siguiente comando: grep -E '[0-9]{3}' /etc/passwd, cuál es su resultado

P16: Regex: Pero el ojo humano primero
  Ahora usaremos el comando wc para mostrar estadísticas sobre el resultado del comando "ls -l".
  Muestra el número de directorios contenidos en /etc

P17: Regex
  Muestra el número de archivos normales contenidos en /etc

P18: Regex
  Muestra el número de archivos que tienen más de un enlace (el segundo numero tiene que ser superior a 1).
  Esta es dificil, puedes ver directo la repuesta ;-)


P20: Regex
  Ahora en adelante, las preguntas son mucho mas rápidas:
  Solo escribe la expresión regular que permitiría agarrar tal linea en el commando:
  > grep -P 'Aqui_esta_la_exprecion'

P21: Regex tiene una 'q'
P22: Regex comienza con una 'q'
P23: Regex tiene 'th'
P24: Regex tiene una 'q' o una 'Q'
P25: Regex tiene un '*' en él
P26: Regex comienza con una 'q' o una 'Q'
P27: Regex tiene 'a' y también 'e'
P28: Regex tiene una 'a' y en algún lugar después una 'e'
P29: Regex no tiene una 'a' ! Esa no la hemos visto, mira la repuesta.
P30: Regex no tiene una 'a' ni una 'e'
P31: Regex tiene una 'a' pero no una 'e'
P32: Regex tiene al menos 2 vocales consecutivas (a, e, i, o, u) como la "io" de la palabra "rocio"
P33: Regex tiene al menos 3 vocales
P34: Regex tiene al menos 6 caracteres
P35: Regex tiene exactamente 6 caracteres
P36: Regex 'Bar' o 'Baz'


End:
  Acabaste, felicitación, ya eres padawan en Regex.
  Créeme que son muy muy útiles.
  Desafortunadamente no puedo mostrarte todo los campos en que son usadas.

  Lo interesante es que son usadas el la misma interpretación de todo los lenguajes informáticos.
  Así que tienes todas la llaves para hacer tu propio idioma!

  Nos vemos para los servicios.


+==================+
| Regex: Repuestas |
+==================+

R11: grep -P '.y' /etc/passwd
R12: grep -P 'root|bin|sync' /etc/passwd
o
grep 'root\|bin\|sync' /etc/passwd
Nota que es mas fácil (menos escapes con -P para PCRE)
R13: Busca las cadenas de caracteres ("string") "nob" o "non".
El efecto de la paréntesis es la agrupar lo que esta adentro como si fuera un átomo.
Si las sacamos, la expresión regular busca "nob" o "n";
R14: head -n 5 /etc/passwd | grep \d
sed '6 q' /etc/passwd | grep '\d'
El comando con sed, hace un 'quit' después de imprimir la linea 6. Sed recibe un idioma, asi que es un poco mas versátil y difícil manejar que head que hace solo esta tarea.
R15: Busca cadena de exactamente 3 cifras decimales
R16: Juega, lee la doc de ls o pregunta a un motor de búsqueda.
Fíjate que los directorios empiezan con un "d":
> ls -l /etc | grep -P '^d' | w
R17: Lo mismo, no tiene que empezar con "d", ni "l" (para Link) sino "-" aparentemente cierto?
> ls -l /etc | grep -P '^-' | w
R18: ls -l /etc | grep -P '^\S+ +1 '
  ^  = principio de linea
  \S = ALgo que no sea un espacio (o tabulacion)
  +  = Ultimo atomo 1 o mas veces
  <space> = espacio literal
  +  = uno o mas veces
  1  = "1" literal
R21: q  # literal
R22: ^q  # ^ para principio de linea
R23: th  # literal
R24: q|Q  # | para alternación
R25: \*   # Se debe escapar porque sino es el cuantificador de 0 a infinito osea cualquier numero de veces
R26: ^(q|Q)  # Hay que agrupar porque "^q|Q" coincide con lineas que comienzas con una q o tienen un Q (en cualquier lugar ya que la alternación tiene precedencia muy baja)
R27: a.*e|e>*a  # A seguido poor e o e seguido por a. Deba haber otras formas
R28: a.*e  # a, . = cualquier cosa, * = cualquier numero de veces, e
R29: ^[^a]*$
^ = principio de linea
[^a]  = es una clase de carácter, y el "^", si esta al principio lo niega, entonces aquí es todo excepto un "a".
  Puedes ver mas sobre las clases de caracteres en internet, lo importante aquí es que es una alteración que permite "coincidir con todo excepto".
$ = fin de linea
R30: ^[^ae]*$  # Principio de linea, ni a ni e cualquier numero de veces, fin de linea
R31: ^[^e]*a[^e]*$  # Principio, non-e cualquier numero de caves, a, non-e cualquier veces, Fin
R32: [aeiou]{2}  # a, e, i, o o y repetido exactamente 2 veces
R33: ^(.*[aeiou]){3}  # Principio de linea (no necesario pero mas rapido), lo que sea seguido por una vocal, y todo eso repetido 3 veces.
Debería empezar a entra un poco. La idea es que veas lo que se puede hacer.
R34: ^......  # o "^.{6}" que es lo mismo: cualquier caracter 6 veces.
R35: ^.{6}2311507cend  # principio, cualquier carácter 6 veces, fin
R36: Ba(r\z)  # Y se acabo, Bravo!



linux81
-------
System: Servicio y Servidor:

# Mira que aplicacion que cononce tu cortafuego
sudo ufw app list

# Instala nginx
sudo apt install nginx

# Mira que aplicacion que cononce tu cortafuego ahora
# La magia de la instalacion: Aparece "Nginx HTTP"
sudo ufw app list

# Permite a Nginx de escuchar en el puerto HTTP (el numero 80)
sudo ufw allow 'Nginx HTTP'

# Analisa el estatus del cortafuego
sudo ufw status

# Analisa el estatus de nginx
systemctl status nginx

# Si no esta prendido lee y resuelve los errores
# -- en mi caso, apache2 esta ocupando el puerto 80, lo tuve que parar
# -- lo encontre asi:
netstat -laputn | grep 80
# -- lo mate asi con kill -15, y si no para kill -9

# Asegurate que nginx cumple bien con su funcion:
# -- Que abro el puerto 80 en lectura
netstat -laputn | grep 80
# -- Que entrega bien la pagina
curl -X GET localhost  # En en firefox en la barra de url "localhost"


P07.2: Nginx primer sitio
  Vamos a servir localmente el sitio jim.com


# Crea el directorio del sitio jim.com
sudo mkdir -p /var/www/jim.com/html

# Cambia el dueno y los permisos para que:
# -- 1/ Lo puedas editar
# -- 2/ Nginx lo pueda servir
sudo chown -R $USER:$USER /var/www/jim.com/html
sudo chmod -R 755 /var/www/jim.com

  Crea la pagina de entrada (index.html) del sitio
  Copia la pagina siguiente en /var/www/jim.com/html/index.html
  -->
<html>
  <head>
    <title>Welcome to Jim.com!</title>
  </head>
  <body>
    <h1>Success! The jim.com server block is working!</h1>

    This page is served by Jeimy & Co
  </body>
</html>
  <--

  El sitio web esta hecho, hay que explicar a Nginx como servirlo.
  Es mejor separar la configuracion de cada sitio en un archivo independiente
  Copia la configuracion siguiente en /etc/nginx/sites-available/jim.com

  -->

server {
  listen 80;
  listen [::]:80;

  root /var/www/jim.com/html;
  index index.html index.htm index.nginx-debian.html;

  server_name jim.com www.jim.com;

  location / {
    try_files $uri $uri/ =404;
  }
}
  <--


# Configuraste el sito, habilitalo
sudo ln -s /etc/nginx/sites-available/jim.com /etc/nginx/sites-enabled/

# Quizas tendras que descomentar la linea "server_names_hash_bucket_size 64;" en "/etc/nginx/nginx.conf"

# Mira si la sintaxis de tu configuracion esta buena
sudo nginx -t

# Reinicia Nginx
sudo systemctl restart nginx


  Intenta navegar en jim.com. Te redirige a un servidor en internet.


P08: Hosts
  Linux esta "bien" configurado por defecto.
  Es decir configurado para que un cliente pueda navegar en internet sin tener que configurar su piloto de red, sus ruta, sus huespedes conocidos ...
  Por defecto:
  -- El piloto de red es el que se puede connectar al router
  -- Los rutas son las que te dicen el router
  -- Los huespedes son los que te entrega en DNS que ha elejido el router

  Pero tu no quieres seguir la configuracion del router. Tu estas haciendo un proxy inverso => tu eres el router! Y un router de un servidor, no de un cliente tonto.
  Por lo tanto, vamos a configurar tus huespedes conocidos para que cuando busques la IP de jim.com, la pila de la red te devuelva "127.0.0.1" (alias "localhost").
  Suena complicado! Porque lo es. EL la pila de la red, lo puedes configurar:
  -- Localmente: al principio de la pedida o cambiado los route, o haciente un servicio DNS en tu compu
  -- En tu router: Devolviendo la solicitud a tu compu
  -- En internet comprando un nombre de dominio (150 dolares al ano en 2020)

  Mejor hacerlo lo antes possible.
  Esta tarea es complicado pero bastante commun para que el nucleo de Linux haga todo por ti => resulta re facil (como Docker)

# Agrega jim.com a tus huespes conocidos
# -- Para que rediriga a tu computador y no al IP
# -- que te entrega el DNS de internet
sudo echo '127.0.0.1 jim.com' > /etc/hosts

# Prueba de nuevo, navega jim.com en Firefox


P09: Doc: Nginx Archivos importantes
  Ahi esta la clase de Nginx que copie/pegue.
  Tiene un excelente resumen de los archivos de configuracion de Nginx.
  https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-18-04



+==========+
| Servicio |
+==========+

Un servicio es un componente que realiza operaciones en segundo plano sin una interfaz de usuario. (Android developers)
Tambien se llaman demonios (daemons) porque corren en el infr mundo y no tienen ni dios ni ley.
En Linux, a veces, su nombre acaba en "d". Ejemplo: sshd, httpd, uuidd, osspd. Contra ejemplo: apache, nginx, dovecot


P11: Crea tu primer servicio (php)
  Php es un idioma que ha sido creado justamente para hacer servicios (corriendo en CGI para internet).
  Es muy facil desarollar pero es mas lento y inseguro que java. En nuestro caso es bastante pero nota que los servicios serios (ElasticSearch, Jenkins) estan escrito en java.

  Para crear tu primer servicio, seigue este tutorial:
  https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6


P12: Manipular dynamicamente los servicios
  Juega con el servicio "rot13" que recien creaste para aprender los commandos de manipulacion de servicio.
  https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units


P13: Monitorea tu systema
  Ejecuta estos commandos uno por uno.

top  # q para salir muestra los processsos que los mas usan recursos.
sudo service --status-all  # lista los servicios
systemctl --type=service --state=active  # Lo mismo
cat /proc/meminfo

  Para conocer mas comandos: buscar en internet: "linux monitor system CLI list"


P14: Interactua Nginx

# To stop your web server, type:
sudo systemctl stop nginx

# To start the web server when it is stopped, type:
sudo systemctl start nginx

# To stop and then start the service again, type:
sudo systemctl restart nginx

# If you are simply making configuration changes, Nginx can often reload without dropping connections. To do this, type:
sudo systemctl reload nginx

# By default, Nginx is configured to start automatically when the server boots. If this is not what you want, you can disable this behavior by typing:
sudo systemctl disable nginx

# To re-enable the service to start up at boot, you can type:
sudo systemctl enable nginx


End:
  Acabaste esta penultima clase. Felicitacion!

  Configuracion (hemos visto):
  Nota que todo pasa por la configuracion ya que los servicios corren sin interacion directa con el usario.
  El dia que tengas que hacer un servidor de correos electronicos, vas a jugar mucho con configuraciones: no codigo imperativo sino declaraciones de configuraciones.
  Este dia, no olvides el ciclo de desarollo de programas porque la declaracion de configuracion es, al final, desarollo informatico.

  Pilotos (mas alla):
  Creaste un servicio, es mas complicado que un procesos normal, sobre todo para interactuar con ese.
  Un piloto es un servicio que corre en el nucleo. Asi que crear, cargar, interactuar con servicios es el camino natural para crear pilotos.
  El proceso para isntalar un piloto es exactamente igual (crear, cargar, interactuar).
  La diferencia reside en el codigo ya que el piloto (en el nucleo) no puede usar todo lo que existe en el espacio usario. Ademas, en el nucleo, el error es mas imperdonable. Aunque hoy dia, los modulos nucleo pueden tener errores irecuperables sin provocar un kernel panic.

  Tag: > nginx > ufw > systemctl
  

+========+
| Servir |
+========+

Un servicio es la operacion de servir. Aqui es un programa que hace una tarea de servicio.
Un servidor es una machina que aloja servicios.

En esta clase, usaste mis servicios (sshd) y los de wikipedia (httpd). Cuando te connectaste como cliente via ssh o http.
Nota que el d significa "demonio" en el sentido "sin dios ni ley" en el sentido actua solo, sin usario => es un servicio!
Aloja (es decir ejecuta) uno de estos y eres un servidor!

0/ Antes de empezar: que servicios estan corriendo en tu machina ahora?
1/ Primero vamos a correr servicio el mas simple: de los 90 en Python: un servicio de systema de archivos
2/ Despues algo un poco mas potente: de los 2000 en Java: Apache: un proxy de servicio, y el systema cgi que ha sido tan util
-- En este contexto (2000), hablaremos de Php y porque esta mal. Porque Ruby es merjor pero igual esta mal. Porque Python y Java, los mas viejos, todavia la llevan en 2020. Porque Java es mejor que Python. Y nos lleva a 2020:
3/ Pues vamos a ver, en 2020, un servicio completo (que uso), se llama Jenkins, esta en Java pero sin Apache, lo instalaremos.
Tambien hablaremos de ElasticSearch totalmente en Java con Kibana tambien en Java que muestran lo que existe hoy. Vas a aceder al mio porque hay que instalar Apache y es pesado.
4/ Para acabar: vamos a hacer un sitio en internet (con tu CV y 2 paginas, en 20 minutos!)


+==========+
| Servidor |
+==========+

En informática, un servidor es una pieza de hardware o software (programa informático) que proporciona funcionalidad para otros programas o dispositivos, llamados clientes. (Wikipedia)

P01: Interface a los servicos (service o systemctl):
  > service  # Aqui listeas los servicios presentes (ejecutandose [+] o no [-])
  Ssh : ya no conoces, permita connectarse con terminales y ejecutar commandos sobre otras machinas
  Cron: para cronological, es un servicio que ejecuta cosas (que tu defines) cada cierto tiempo. Respaldos, Synchronisacion, Compilacion. Es bakan pero hay que "tener la mano" sobre el servidor (tu machina) para configurarlo, lo que a veces es overkill (hay que hacer un ssh).
  Httpd: No lo tienes me imagino, prove una interface http, permite connectarse con mozilla firefox, que a veces es mas rapido que con terminal (mas amigable al usario)

  No vamos a ver sshd (que haces su pega solo) ni de cron (que solo ejecuta los archivos en /etc/cron.hourly) cada hora).
  Vamos a estudiar otros servicios que usan httpd. Los servicios pueden usar servicios. Abusando de eso es recomandado y llega a la architectura de micro servicios. Es mas resiliente ya que evita los puntos unicos de fracaso.

  Aparte:
  > systemctl -h  # -h = help. Se supone que es mejor que service pero me cuesta usarlo, usamos el coando service no mas
  Fin del Aparte


P02: Netcat: Http: Servicio Hello World
  while true; do { echo -e 'HTTP/1.1 200 Hello World
'; sh test; } | nc -l 8081; done

  En Firefox, navega: localhost:8081

  Nota que, desafortunadamente, BaSh no tiene el poder de abrir un socket en escucha.
  En la implementacion de BaSh, se ve que usa solo la llamada systema de interacion con scoket con "connect" (cliente) y no "bind" servidor
  Fuente: https://unix.stackexchange.com/a/49947/257838


P03: Python: Servidor Http basico:
  > cd  # Sin argumentos, va a casa (obvimente el lugar por defecto, es tu casa)
  > python3 -m http.server  # Ctrl-c para acabar
  -- Navega los directorios
  -- Abre una pagina html
  -- Admira la semejancia entre el URL (enlnace en firefox) y el camino en el filesytem: y si lo corres con PWD en /?


P04: CGI: Common Gateway Interface
  Para crear tu primer servidor CGI, sigue este tutorial:
  https://code-maven.com/set-up-cgi-with-apache


P05: Pagina Github
  Esta es la mia: https://tinmarino.github.io/
  Aqui estan los archivos: https://github.com/tinmarino/tinmarino.github.io (esta un poco desordenado <= me da miedo borrar cosas)

  Para hacer el tuyo, lo mismo remplazando tinmarino con tu cyber nombre. No Puede ser Jim, tiene que ser mas largo! Tienes un nombre de hacker? Tienes que encontrarte uno: todos tenemos: SilverFox, DarkPsychoz, Ochod, Milkyway, NanoHate, Tinmarino
  NO: Jsan (tomado)
  NO: JimSan (tomado)
  NO: JackySan (tomado)
  NO: JaiSan (tomado)
  OK: JaimeSan (pero feo)
  OK: JaimeSanhueza (por mientras)

  1/ Create una cuenta github
  2/ Crea un repositiio nombre_de_cuenta.github.io  # Remplaza nombre_de_cuenta por tu nombre de cuenta (usario)
  3/ Sigue lo que dice para tener el repo en tus archivos locales
  4/ Pon una pagina html o tu cv en pdf
  5/ Empuja
  6/ Visita tu pagina y admira como hiciste una pagina permanente en 20 minutos!


P06: Route
  Read this: https://www.cyberciti.biz/faq/ip-route-add-network-command-for-linux-explained


P07.1: Nginx Instalacion
  Nginx es un servidor web, como Apache.
  Puede ser usado como proxy (alias procurador) inverso.
  Es decir que del mismo puerto (80 => HTTP o 443 => HTTPS) redirige distintas solicitudes a dinstintos servicios.





linux82
-------
-- Tarea: wget, cron, cgi, jenkins

  # Inicia un servidor de escucha (en el puerto 8082)
  nc -l 8082

  # Navega con w3m (q para salir)
  w3m http://localhost:8082/

  # Reinicia el servidor (NetCat)
  # Navega con firefox (q para salir)
  firefox http://localhost:8082/

  Analisa las cabezas de la solicitudes.
  En Firefox, puedes abrir la consola de desarolladores para ver las solicitudes y sus cabezas. Seran las mismas que vista desde el servidor.


P13: Manipular dynamicamente los servicios
  TODO


P14: Monitorea tu systema
  TODO

P19: Otros

End:
  * Tarea: openssl for HTTPS https://serverfault.com/questions/102032/connecting-to-https-with-netcat-nc
  * Idea: Web hosting, servidor web, apagche, nginx, ver capitulo 19

  Tag: > w3m
  



linux91
-------
Sintaxis: Lenguaje: Ecosistema: Niveles de idioma


+=======================+
| Languages: Categorias |
+=======================+

P01: Tipos de salida

  Los informáticos operacionales (mal llamados técnicos o ingenieros) clasifican los idiomas en función del tipo de salida que se espera, una pagina web o unos bits para un micro controlador.
  Es interesante para saber que idioma usar en que situación. No se usa un idioma de tipo Asemblados como Shell (sino un interpretado), ni un interpretado para controlar los reactores de una nave (o otro sistema tiempo real)


                           High Level
  |-----------------+------------------------------+-------------------|
  | Familly         | Description                  | Example           |
  |-----------------+------------------------------+-------------------|
  | Domain Specific | Usually short, to manage a   | Git, SQL, Dot     |
  | Language        | tack specific to one domain  | Sed, Awk,         |
  |                 |                              | PCRE (=RegExp)    |
  |-----------------+------------------------------+-------------------|
  | Markup          | Format that describe data:   | Html, Pdf,        |
  |                 | Text, Sound, Video, Web page | Xml, Json, LaTeX, |
  |                 | or metaformat that describes | Css, Markdown,    |
  |                 | it all (Html, Xml)           | Png, Mp3, Mp4     |
  |-----------------+------------------------------+-------------------|
  | Interpreted     | Sent to a program which      | BaSh, Python,     |
  |                 | is executing it while        | Perl, JavaScript, |
  |                 | reading                      | Ruby, Php         |
  |-----------------+------------------------------+-------------------|
  | Pseudo-Compiled | A compiler transform it      | Java              |
  |                 | to pseudo code and a         | Web-Assembly      |
  |                 | virtual machine execurtes    |                   |
  |-----------------+------------------------------+-------------------|
  | Compiled        | Compiled to bytecode by      | C, C++, Rust,     |
  |                 | GNU Compiler Collection      | Fortran, Haskell, |
  |                 | or friends                   | (Cobol, Pascal)   |
  |-----------------+------------------------------+-------------------|
  | Assembly        | Mnemonics that map directly  | Asm, Masm, Nasm   |
  |                 | to machine code operation    |                   |
  |                 | Like Alias for bytecode      |                   |
  |                 | operation                    |                   |
  |-----------------+------------------------------+-------------------|
  | ByteCode        | Binary format (.exe or .so)  | Intel, ARM,       |
  |                 | That is sent to the CPU      | MIPS, RISC        |
  |                 | electromagnetically from     |                   |
  |                 | the RAM                      |                   |
  |-----------------+------------------------------+-------------------|
  | Hardware        | Create instructions to       | VDHL, Verilog     |
  | description     | generate hardware:           |                   |
  |                 | CPU, building                |                   |
  |-----------------+------------------------------+-------------------|
                           Low Level

P02: Tipos de sintaxis
  Pero los investigadores en informática prefieren referirse a su sintaxis y a sus paradigmas.
  Es interesante explicar eso a un alumno, pensar sobre eso para mejorar el código como interfase humano maquina.
  Ayuda en formular operaciones imbricándolas en palabras del idioma variables, funciones o objectos (que son ambos).
  Muestra algo muy importante, es que lo que se entiende bien, se expresa bien, y se ejecuta bien. Así que la elegancia y legibilidad, la sintaxis cuenta.

  * Imperativos
    * Operativos <= Lineares hasta un salto (Asm)
    * Procesal <= con Call, es decir funciones, primera capa de imbricación
    * Orientado Objecto <= con Clases que son contenedores de variables y funciones. Apareció naturalmente después de tanto tiempo guardado las direcciones de las funciones en variables
      -- Es recomendando usar objectos cuando se puede ya que la herencia puede remplazar condiciones
  * Declarativos
    * Funcionales <= El resultado es declarado como una serie de funciones aplicada. Básicamente no hay variables, el código de ejecuta de forma floja lo que permite optimizaciones durante la compilación (Haskell).
      -- Es recomendado usar este paradigma ya que los filtros y cartografías pueden remplazar ciclos.
    * Lógicos <= El humano declara la lógica, las posibilidades y restricciones y el computador encuentra la solución.
      -- Quizás ha sido de modo en los 1980, pero ya no lo es. Lo que es extremamente desafortunado porque el potencial es increíble (Prolog, Gecode)
    * Matemáticos <= El humano escribe una ecuación, el computador la resuelve de forma perfecta. (Mapple, Matematica)


  Notas (importantes):
  1. Cada paradigma soporta un "Nivel mas alto" (Higher level programming) cuando el código genera código: operaciones crean operaciones, funciones que crean funciones, objectos que crean objectos, ecuaciones ....
  2. Se puede hacer cualquier operación con cualquier de estos lenguajes mientras tenga la "completitud de Turing" lo que es el caso de todos los citados excepto los de Markups. Eso dicho, LaTeX que puse en markup es un Macro-Markup como lo puede ser Xml => LaTex, Css son Turing complete (pero es muy hackeo)
  3. Muchos idiomas soportan distintos paradigmas. Se destacan Python y Java que los soportan todos!
  4. Hoy día es muy muy fácil crear un idioma interpretado, se hace mucho para aplicaciones especifica, manejar un avión, controlar una cadena de producción. En ese caso se llama "Lenguaje especifico a un dominio" (Domain Specific Language: DSM).

Esta clase te va a hacer un tour de estos idiomas y las preguntas que te pueden salir relativa a tu cultura programática.
Es mucho mas importante saber leer y depurar código que saber escribirlo.
Lo informáticos dicen: "Un buen programador escribe buen código, un excelente programador reusa buen código".


P03: Lista de idiomas
  Wikipedia: Puedes ver la lista de los lenguajes de programación:
  https://en.wikipedia.org/wiki/List_of_programming_languages

  Stackoverflow: Es el foro donde se responden preguntas relacionadas a la programación. Hace una encuesta anual (muy interesante):
  https://insights.stackoverflow.com/survey/2020#technology-programming-scripting-and-markup-languages

  StackEchange: Y puedes descargar los datos crudos que quieres (en SQL) ahí:
  https://data.stackexchange.com/stackoverflow/query/new

  Github: Es un sitio bastante usado para la fuente abierta.
  Ya que tiene una API, se puede buscar los lenguajes los mas usados.
  El resultado que sigue es coherente con StackOverflow:
  https://github.com/oprogramador/github-languages

  RosetaCode: tiene retazos ("snippets") en todo los idiomas
  Ayuda a la traducción como la piedra de Roseta.
  De ahí saque la mayoría del código que sigue
  http://www.rosettacode.org


+=====================+
| Lenguajes: Ejemplos |
+=====================+

P21: Lenguajes específicos a un dominio (Dot)
  Vamos a ver un idioma de descripción de gráfico: Dot de Graphviz.
  > sudo apt install graphviz
  Copia lo ue sigue en ex.dot

digraph D {

  A [shape=diamond]
  B [shape=box]
  C [shape=circle]

  A -> B [style=dashed, color=grey]
  A -> C [color="black:invis:black"]
  A -> D [penwidth=5, arrowhead=none]

}

  Compila y abre la salid

  dot -Tpng ex.dot -o ex.png
  xdg-open ex.png


P22: Lenguaje de markup (Markdown)
  Markdown tiene la ventaja que se escribe casi como se vee:
  > sudo apt install pandoc
  Copia lo que sigue en ex.md

  -->
# This __bold__ in title

And _italic_ in paragraph
1. A
2. Small
3. List [Link to cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)

And a table:

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

> Blockquotes are very handy in email to emulate reply text.
> This line is part of the same quote.

<p style="color:red">Soporta HTML tag incluido</p>
<p style="color:blue">Lo que es necesario para los colores por ejemplo</p>
  <--

  Compilalo y observa el resultado

  pandoc ex.md -o ex.html && xdg-open ex.html


P23: Lenguaje interpretado (Javascript)
  Javascript es el idioma que corre el el navegador cuando Html y Css no es bastante interactivo.
  Es el lenguaje el mas popular del planeta
  Puedes ver un ejemplo ahí: https://js1k.com/2017-magic/demo/2679
  Abre firefox, aprieta F12, pega lo que sigue en el prompt abajo:

  -->
// Crea una variable
let d = new Date();

// Cambia el contenido de la pagina
document.body.innerHTML = "<h1>Today's date is " + d + "</h1>"

// Cambia el estylo
document.body.style.backgroundColor = "lightblue";

// Crea nodos = tag dynamicamente
let p = document.createElement("P");
let t = document.createTextNode("Paragraph text.");
p.appendChild(t);
document.body.appendChild(p);
  <--

  Nota que cuando JavaScirpt encuentra errores, sigue la ejecución igual.
  Es un idioma interpretado con una especificación perfectamente descrita para que se ejecute igual en distintos navegadores, para que Internet funciones
  Es un poco lento, por eso nació en WebAssembly


P24: Lenguaje Pseudo Compilado (Java)
  Java es el ejemplo natural de esta categoría.
  > sudo apt install default-jre
  Copia en Ex.java

  -->
public class Ex {
    public static void main(String[] args) {
        for (int i = 1; i <= 12; i++)
            System.out.print("\t" + i);

        System.out.println();
        for (int i = 0; i < 100; i++)
            System.out.print("-");
        System.out.println();
        for (int i = 1; i <= 12; i++) {
            System.out.print(i + "|");
            for(int j = 1; j <= 12; j++) {
                if (j >= i)
                    System.out.print("\t" + i * j);
            }
            System.out.println();
        }
    }
}
  <--

  # Pseudo-compilalo (Java Compiler)
  javac Ex.java

  # Ejecutalo (el la Java Virutal Machine)
  java Ex

  # Intenta leer el archivo Ex
  cat Ex  # Oups no existe ...

  # ... Porque es Ex.class
  cat Ex.class  # Asi se ve un codigo pseudo compilado


P25: Lenguaje Compilado (C)
  C es el idioma compilado mas usado. Es un idioma sistema, permita comunicar con el núcleo o adentro del núcleo con los dispositivos.
  Se puede compilar para muchas arquitecturas distintas.
  Los núcleos de Linux y Windows están escrito en C, hoy (2020) se debe escribir en C un piloto Linux. Windows permite C++
  Su único rival es Rust (todavía guaguita)

  -->
#include <stdio.h>

void pascaltriangle(unsigned int n)
{
  unsigned int c, i, j, k;

  for(i=0; i < n; i++) {
    c = 1;
    for(j=1; j <= 2*(n-1-i); j++) printf(" ");
    for(k=0; k <= i; k++) {
      printf("%3d ", c);
      c = c * (i-k)/(k+1);
    }
    printf("\n");
  }
}

int main()
{
  pascaltriangle(8);
  return 0;
}
  <--

  # Compila (Gnu Compiler Collection)
  gcc ex.c -o ex

  # Correlo (Como cualquier ejecutable
  ./ex


P26: Lenguaje Asemblado (Nasm)
  Nasm es un lenguaje asemblado abierto.
  > sudo apt install nasm
  También cada fabricante de procesador tiene su propio idioma.
  Gcc los conoce todos.
  Escribe e un archivo hello.asm:

  -->
; Define variables in the data section
SECTION .DATA
	hello:     db 'Hello world!',10
	helloLen:  equ $-hello

; Code goes in the text section
SECTION .TEXT
	GLOBAL _start

_start:
	mov eax,4            ; 'write' system call = 4
	mov ebx,1            ; file descriptor 1 = STDOUT
	mov ecx,hello        ; string to write
	mov edx,helloLen     ; length of string to write
	int 80h              ; call the kernel

	; Terminate program
	mov eax,1            ; 'exit' system call
	mov ebx,0            ; exit with error code 0
	int 80h              ; call the kernel
  <--

  # Assembla lo
  nasm -f elf64 hello.asm -o hello.o

  # Linkealo
  ld hello.o -o hello

  # Executalo
  ./hello

  También puedes generar código asemblado desde codigo c.
  Escribe hi.c;

  -->
#include <stdio.h>

int main(int argc, char** argv){
  printf("Hi Jim\n");
  return 0;
}
  <--

  # Assemblealo (en Gas para Gnu ASsembly)
  gcc hi.c -S -o hi.S

  # Mira el codigo assembly (:q! para salir)
  vi hi.S

  # Compilalo
  gcc -c hi.S -o hi.o

  # Linkealo
  gcc hi.o -o hi

  # Executalo
  ./hi


P27: Lenguaje binario (Bin)
  El código binario esta escrito en 0 y 1 como 0000101101110001.
  Pero es mas eficiente verlo en hexadecimal donde
  00 -> 00000000
  FF -> 11111111

  No vamos a escribir código binario pero lo vamos a leer (en hexadecimal)

  # Desassemblealo:
  # -- En segmento .DATA como string <= s
  # -- El segmento .TEXT como codigo desassembleado <= d
  objdump -sj .DATA hello && objdump -dj .TEXT hello

  # Mira su contenido crudo
  cat hello | xxd

  # Lo quieres ver con 1 y 0?
  cat hello | xxd -b


P28: Lenguaje descriptivo de hardware (VHDL)
  Para crear un CPU, ya no se dibuja cada circuito.
  Se escribe las especificaciones (lo que uno quiere en entrada y en salida) que, pasando por un generador, crean un archivo que describe la arquitectura, posición de los circuitos.
  El primer CPU (Controlador) que se crear vale 1 millón de dolares porque hay que configurar las maquinas para eso. Los siguientes valen menos de 1 dolar cada uno. Por lo tanto se crean millones de una, hay que estar seguro antes de mandar el plan a Vietnam o China.
  Por eso existen field-programmable gate array (FPGA) que son procesadores que se pueden configurar. Pueden servir para hacer los prueba del código VDHL o para tener un CPU con operaciones especificas.

  sudo apt install ghdl

  Escribe en counter.vhdl:

  -->
-- Importa las bibliotecas, necesario para los IO (aqui solo reset para acabar)
library ieee ;
use ieee.std_logic_1164.all;

-- Declara las entradas y salidas de esta entidad
entity counter is
  port(
    reset:  in  std_logic
  );
end;

-- Implementa el trabajo de la entidad
architecture behav of counter is
begin
  -- Declare un proceso con nombre, que solo se lanza al reset
  count_to_10: process(reset)
  begin
    -- Da 10 vuelvas
    for I in 1 to 10 loop
       -- Imprime la concatenacion "&" de un literal y del valor de la variale I (entera)
       report "I = " & integer'image(I);
    end loop;
  end process;
end behav;
  <--

  # Analysa (es como compilar)
  ghdl -a --ieee=synopsys counter.vhdl

  # Genera el Ejecutable
  ghdl -e --ieee=synopsys counter

  # Corre (Run) en un component FPGA virtual
  ghdl -r --ieee=synopsys counter



End:
  Hemos visto un zoológicos de idioma del código a la ejecución.

  Acuérdate que hay distintas forma de catalogar un lenguaje (nivel de ejecución, sintaxis) pero no hay idiomas "malos", "complicados" o "débiles".
  El "débil" es el humano que pronuncia esta palabras porque es "complicado" trabajar con este weon "malo".
  Por lo tanto, no temes ni el nivel de ejecución, ni el tipo de sintaxis y entraras en la familia de los informáticos agnósticos del idioma ("lenguaje agnóstico software enginneers"). Lo mejor de esta familia, es que el boleto de entrada es gratis. Bienvenido!

  Tag: > dot > pandoc > xdg-open > gcc > java > javac > ld > nasm > hexdump > xxd > ghdl
  



linux92
-------
-- Tarea: Zoo de lenguajes


+===================+
| Lenguaje: Tarea  |
+===================+

Lo mejor es aprender manos arriba.
Por eso vamos a jugar en el sitio: https://www.hackerrank.com

P00: Crear cuenta
  Crea una cuenta al sitio de desafió de programadores: https://www.hackerrank.com

+=========================+
| Lenguaje: Interpretado  |
+=========================+

P01: Python: Hello World
  Imprime "Hello world" en la salida estándar:
  https://www.hackerrank.com/challenges/py-hello-world/problem


End:

  



linux93
-------
-- Examen: fin de cyclo


+============+
| Examen 1/2 |
+============+
  
End:
  



misc
----
Misceláneo: Recursos para las clases

  Usage: misc.sh [options] function
  Function list:
  --------------
  args
  Debug: Print Arguments passed

  link
  

  Option list:
  ------------
  --doc
  Print documentation (longer than help)

  --help
  Print this message

  --print
  Only print command instead of executing