5 Agosto 2008 · Etiquetas: Bash, Sistemas
Bash tiene un gran soporte de comparadores de todo tipo que nos permiten hacer comparaciones en los bucles y crear condiciones de todo tipo:
Comparación de enteros (números)
- -eq
es igual a
if [ "$a" -eq "$b" ]
- -ne
no es igual a / distinto
if [ "$a" -ne "$b" ]
- -gt
es mayor que
if [ "$a" -gt "$b" ]
- -ge
es mayor que o igual a
if [ "$a" -ge "$b" ]
- -lt
es menor que
if [ "$a" -lt "$b" ]
- -le
es menor que o igual a
if [ "$a" -le "$b" ]
- <
es menor que (dentro de doble paréntesis)
(("$a" < "$b"))
- <=
es menor que o igual a (dentro de doble paréntesis)
(("$a" <= "$b"))
- >
es mayor que (dentro de doble paréntesis)
(("$a" > "$b"))
- >=
es mayor que o igual a (dentro de doble paréntesis)
(("$a" >= "$b"))
Comparación de cadenas
- =
es igual a
if [ "$a" = "$b" ]
- ==
es igual a
if [ "$a" == "$b" ]
Nota: Aunque es un sinónimo de = el operador == se comporta diferente cuando se usa dentro de corchetes dobles que simples, por ejemplo:
[[ $a == z* ]] # Verdadero si $a empieza con una "z" (expresión regular coincide).
[[ $a == "z*" ]] # Verdadero si $a es igual a z* (coincide literalmente).
[ $a == z* ] # Ocurre división de palabras.
[ "$a" == "z*" ] # Verdadero si $a es igual a z* (coincide literalmente).
!=
no es igual a / Distinto
if [ "$a" != "$b" ]
NOTA: este operador usa coincidencia de patrón dentro de doble corchete.
<
es menor que (en orden alfabético ASCII)
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
Nota: el operador “<” necesita ser escapado dentro de corchetes.
>
es mayor que (en orden alfabético ASCII)
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
Nota: el operador “>” necesita ser escapado dentro de corchetes.
-z
La cadena está vacía (nulll), tiene longitud cero.
cadena='' # Variable de longitud cero (null)
if [ -z "$String" ]
then
echo "\$String está vacía."
else
echo "\$String no está vacía."
fi
-n
cadena no está vacía (contiene algo)
nota: El operador -n exige que la cadena esté entre comillas entre paréntesis. Aunque el uso son comillas puede funcionar es altamente recomendable usar comillas.
Comparaciones lógicas
Éstos últimos operadores son similares a los operadores de Bash && (and) y || (or) cuando se usan con doble corchete:
[[ condition1 && condition2 ]]
4 Agosto 2008 · Etiquetas: Aplicaciones, Bash, Shell
A veces cuando tenemos muchas pestañas abiertas en el iTerm, especialmente en la misma shell (ya sea local o remota) nos interesa poder distinguirlas. Bien el propio iTerm permite hacerlo, pulsando manzana+i (⌘+i) nos aparece una ventana en la cual podemos cambiar el nombre en el campo “name”.

También podemos añadir un texto a este nombre desde la shell usando un simple echo con una secuencia de escapes:
echo "^[]1;texto^G"
NOTA: NO vale copiar y pegar ya que no funcionará, ^] es control+v y luego esc, ^G es control+v y luego control+g, es muy importante.
Con esto añadimos a la pestaña “texto” a lo que ya estuviera:

También podemos usar otro tipo de escape que es básicamente lo mismo:
echo -ne "\033]0;texto\007"
Lo interesante de esto es que el texto puede ser una variable o una función de Bash o lo que queramos con lo cual podemos añadir que nos indique el path o directorio actual:
echo "^[]1;${PWD/#$HOME/~}^G"
El problema de esto es que no es dinámico y si nos cambiamos de directorio no se cambia a menos que coloquemos esa cadena de escape en la variable PS1 que se encarga de cambiar el prompt:
PS1="\[\033]0;\u@\h: \w\007\]\u@\h:\W>"
Con lo que tanto el prompt como la pestaña se irán actualizando (usuario@host:path>) según vayamos cambiando de directorio.
Yo personalmente como prompt uso el siguiente que es a color y doble línea:
PS1="\[\033[33m\]\\u\[\033[37m\]@\[\033[32m\]\\H\[\033[37m\]:\[\033[36m\]\\w\[\033[37m\]\n\\$ "
Si además queremos que nos actualice la pestaña (solo el path para que se vea mejor y más útil):
PS1="\[\033]0;\w\007\]\[\033[33m\]\\u\[\033[37m\]@\[\033[32m\]\\H\[\033[37m\]:\[\033[36m\]\\w\[\033[37m\]\n\\$ "
Esto lo podemos meter en el fichero .bash_profile de nuestra home:
# Actualiza prompt y pestaña
export PS1="\[\033]0;\w\007\]\[\033[33m\]\\u\[\033[37m\]@\[\033[32m\]\\H\[\033[37m\]:\[\033[36m\]\\w\[\033[37m\]\n\\$ "
# Actualiza solo prompt
export PS1="\[\033[33m\]\\u\[\033[37m\]@\[\033[32m\]\\H\[\033[37m\]:\[\033[36m\]\\w\[\033[37m\]\n\\$ "
NOTA: solo puede estar activo uno de los dos así comenta o borra el que no quieras.
3 Agosto 2008 · Etiquetas: Bash
Un bucle es un trozo de código que repite la ejecución de un comando o comandos mientras la condición es verdadera. Bash tiene diferentes formas para realizar bucles (for, while, until).
- FOR
Tiene dos formatos, uno tipo lenguaje C y otro totalmente diferente:
for variable in [lista]
do
comando(s)...
done
for ((variable=valor_inicial; a <= limite ; incremento))
do
comando(s)...
done
- WHILE
while [ condicion ]
do
comando(s)...
done
- UNTIL
until [ condicion ]
do
comando(s)...
done
NOTA: si el do va en la misma línea que el for, while o until, antes del do debe haber un ‘;‘. Por ejemplo: “for variable in [lista]; do”.
También como en otros lenguajes podemos tomar el control de los bucles con los siguiente comandos:
- Continue, provoca que se salte al siguiente valor de la lista o condición ignorando el resto de comandos que haya por debajo.
- Break, provoca que se salte al siguiente comando justo seguido del bucle aunque este no haya terminado, es una ruptura del bucle.
—- Ejemplos —-
* Bucle FOR simple:
#!/bin/bash
for numeros in 1 2 3 4 5 6 7 8 9
do
echo $numeros # cada numero en una linea separada
done
echo
for numeros in "1 2 3 4 5 6 7 8 9"
# Todos los número en la misma linea.
# Una lista entre comillas crea una única variable.
do
echo $numeros
done
Salida:
1
2
3
4
5
6
7
8
9
1 2 3 4 5 6 7 8 9
* Bucle FOR con dos valores en cada elemento de la lista:
#!/bin/bash
# Asociar cada planeta con su distancia del sol.
for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"
do
set -- $planet
# divide los valores y crea parámetros posicionales ($1, $2 ...)
# "--" evita problemas si $planet empieza con guiones o es una cadena vacía.
echo "$1 $2,000,000 millas del sol"
#-------2 tabuladores-añade ceros al parámetro $2
done
salida:
Mercury 36,000,000 miles from the sun
Venus 67,000,000 miles from the sun
Earth 93,000,000 miles from the sun
Mars 142,000,000 miles from the sun
Jupiter 483,000,000 miles from the sun
NOTA: Como “set — $planet” sobre escribe los valores de los parámetros $1, $2, etc puede ser necesario guardar los varoles para después recuperarlos. Esto lo podemos hacer con el uso de un array: parametros_originales=(”$@”)
* Bucle FOR al estilo C:
#!/bin/bash
LIMITE=9
for ((a=1; a < = LIMITE ; a++)) # Doble paréntesis y "LIMITE" sin "$".
do
echo -n "$a " # -n = no añade retorno de carro
done
echo
salida:
1 2 3 4 5 6 7 8 9
* Bucle WHILE simple:
#!/bin/bash
LIMITE=10
a=1
while [ "$a" -le $LIMITE ]
do
echo -n "$a " # -n = no añade retorno de carro
let "a+=1"
done
echo
salida:
1 2 3 4 5 6 7 8 9 10
* Bucle UNTIL simple:
#!/bin/bash
LIMITE=10
a=1
until [ "$a" -ge $LIMITE ]
do
echo -n "$a " # -n = no añade retorno de carro
let "a+=1"
done
echo
salida:
1 2 3 4 5 6 7 8 9 10
10 Abril 2008 · Etiquetas: Aplicaciones, Bash, Musica
Script para convertir de forma cómoda y automática CDs completos en formatos LOSSLESS (sin perdida) a MP3 para poder reproducirlos en reproductores tipo IPOD.
Descarga la última versión: te2mp3_v0.6.1.sh
La ayuda es la siguiente y puede verse ejecutando el script sin parámetros:
Usage:
./te2mp3_v0.6.1.sh -c CUE_file -f sound_file [-y YEAR] [-g genre] [-o output_directory] [-u] [-r] [-l]
./te2mp3_v0.6.1.sh [-l] [-o output_directory] -b batch_file
./te2mp3_v0.6.1.sh -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac
./te2mp3_v0.6.1.sh -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998
./te2mp3_v0.6.1.sh -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998 -g 138
./te2mp3_v0.6.1.sh -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998 -o /home/the_evangelist/music -g 138 -u
./te2mp3_v0.6.1.sh -b batch_file
NOTE: -u = change espaces for underscores (Optional)
NOTE: -g = Genre, to see list 'id3v2 -L' (Optional)
NOTE: -r = do not remove temporaly CUE and WAV files (default is remove)
NOTE: -l = create a letter (first letter of band name) directory before band name directory:
NOTE: in Batch mode -l and -o MUST be before -b option)
NOTE: -b = Batch mode has this format (for each file to process):
AUDIO file (including path to)
CUE file (including path to)
YEAR
GENRE (to see list 'id3v2 -L')
UNDERSCORE (1 = yes, any other = no)
---------------------------------------------------------------------
bash -> Necessary to run this script (Mandatory)
cueprint -> get info from CUE files (Mandatory)
lame -> for compressing MP3 files (Mandatory)
shntool -> for xtracting WAV from compress files (Mandatory)
perl -> For renaming white spaces to underscores (Mandatory)
mac -> for decompressing APE files (Optional)
flac -> for decompressing FLAC files (Optional)
wavpack -> for decompressing WV files (Optional)
hope in future versions will not be necessary
---------------------------------------------------------------------
CHANGELOG
- 2006-04-22 <-> v0.6.1
- * Fix Album name problem, change ‘/’ for ‘-’ in Album name
- * Fix, check if Batch file exists if not show error and exit
- 2006-04-17 <-> v0.6
- * change all SED, now using builtin Bash Strings Manipulation
- now script more portable and one external program less
- + added option -l to create directory before band name (b/bathory)
- + added more comments and corrected some grammar
- + Now illegal option is print in RED
- + Now -o OUTPUT can be used in Batch mode
- 2006-04-16 <-> v0.5
- * Reorganice script in functions
- + added batch process (-b ) to convert several files rapidly
- + added by default genre “Metal” (9), instead of nothing
- * Fix name problem, change ‘/’ for ‘-’ in title name and mp3 file
- * Fix problem (ALBUM_DIR) when year (-y) is NOT specified
- 2006-04-15 <-> v0.4.1
- * Fix problem with CUE, first line must be FILE “….”
- now hope will be resolved forever
- - cueconvert no more needed
- 2006-04-14 <-> v0.4
- * Fix problem when renaming white spaces
- * Some fixes and improvements
- + added option -r to remove or not temporal CUE and WAV files
- + added required commands
- + added more comments
- 2006-04-13 <-> v0.3
- + added capitalize all words
- NOTE: change perl to sed or something else
- * Fix CUE bug
- + added –add-id3v2 option to lame
- force addition of version 2 tag
- 2006-04-12 <-> v0.2
- + added support for parameters (getopts)
- + added support for genre
- + added destination path (optional) default current
- * several bugfixes
- 2006-04-10 <-> v0.1
21 Marzo 2008 · Etiquetas: Bash
Si en la línea del CLI o un script de este tipo:
for LINEA in $(find _directorio_ _que_buscar_ )
do
echo $LINEA
done
nos aparece uno o más espacios no nos saldrá la salida como esperamos
ya que el for interpreta el espacio como un separador con lo cual en vez de tener un listado como este (es un mero ejemplo):
linea1
linea2
linea 3
linea4
obtendremos un listado como este:
linea1
linea2
linea
3
linea4
que está claro no es lo que buscamos :-(.
Para solucionar esto basta con añadir una simple línea delante del For para que “ignore” los espacios y obtengamos el listado como queremos:
export IFS=$'\n'
for LINEA in $(find _directorio_ _que_buscar_ )
do
echo $LINEA
done
29 Octubre 2007 · Etiquetas: Bash
- Pasar de fecha a número de segundos desde la época
date --date='1970-01-01 00:00:01' +%s
1
date --date='2000-01-01 00:00:01 UTC' +%s
946684800
- Pasar de segundos desde la época a fecha
date -d '1970-01-01 1 sec' +"%Y-%m-%d %T %z"
1970-01-01 00:00:01 +0100
date -d '1970-01-01 946684800 sec' +"%Y-%m-%d %T %z"
2000-01-01 00:00:00 +0000
- ceros delante de las fechasPor ejemplo si te encuentras con este error:current month is 08 it gives me this error. value too great for base (error token is “08″)
Revisa la forma de obtener las fechas. (NOTA: lo del guión es válido para cualquier fecha y hora).
date "+%-m"
9
date "+%m"
09
31 Julio 2007 · Etiquetas: Bash, Debian, Seguridad
Instalar el paquete debian-keyring de la siguiente manera:
apt-get install debian-keyring
Si sale este error o similar:
W: GPG error: http://secure-testing.debian.net etch/security-updates
Release: The following signatures couldn't be verified because the public
key is not available: NO_PUBKEY 946AA6E18722E71E
Coger los últimos 8 dígitos de la pubkey (en el ejemplo de arriba: 8722E71E) y ejecutar los siguientes comandos:
$ gpg --keyserver pgp.mit.edu --recv-keys 8722E71E
$ gpg --armor --export 8722E71E | apt-key add -