GNU/Linux >> Tutoriales Linux >  >> Linux

Más trucos estúpidos de Bash:variables, búsqueda, descriptores de archivos y operaciones remotas

Esta publicación de blog es la segunda de dos que cubren algunos consejos y trucos prácticos para aprovechar al máximo el shell Bash. En la primera parte, cubrí la historia, el último argumento, el trabajo con archivos y directorios, la lectura de archivos y las funciones de Bash. En este segmento, cubro variables de shell, búsqueda, descriptores de archivos y operaciones remotas.

Usar variables de shell

Las variables de Bash las establece el shell cuando se las invoca. ¿Por qué debería usar hostname? cuándo puedo usar $HOSTNAME, o por qué debería usar whoami ¿Cuándo puedo usar $USER? Las variables Bash son muy rápidas y no requieren aplicaciones externas.

Estas son algunas variables de uso frecuente:

$PATH
$HOME
$USER
$HOSTNAME
$PS1
..
$PS4

Usa el echo Comando para expandir variables. Por ejemplo, la variable de shell $PATH se puede expandir ejecutando:

$> echo $PATH

[ Descargar ahora:una guía para administradores de sistemas sobre secuencias de comandos Bash. ]

Utilice el comando de búsqueda

El find command es probablemente una de las herramientas más utilizadas dentro del sistema operativo Linux. Es extremadamente útil en shells interactivos. También se utiliza en guiones. Con find Puedo enumerar archivos más antiguos o más nuevos que una fecha específica, eliminarlos en función de esa fecha, cambiar los permisos de archivos o directorios, etc.

Familiaricémonos más con este comando.

Para listar archivos con más de 30 días, simplemente ejecuto:

$> find /tmp -type f -mtime +30

Para eliminar archivos de más de 30 días, ejecute:

$> find /tmp -type f -mtime +30 -exec rm -rf {} \;

o

$> find /tmp -type f -mtime +30 -exec rm -rf {} +

Si bien los comandos anteriores eliminarán archivos de más de 30 días, tal como están escritos, bifurcan el rm comando cada vez que encuentran un archivo. Esta búsqueda se puede escribir de manera más eficiente usando xargs :

$> find /tmp -name '*.tmp' -exec printf '%s\0' {} \; | xargs -0 rm

Puedo usar find para listar sha256sum archivos solo ejecutando:

$> find . -type f -exec sha256sum {} +

Y ahora para buscar y deshacerse de los archivos .jpg duplicados:

$> find . -type f -name '*.jpg' -exec sha256sum {} + | sort -uk1,1 

Descriptores de archivos de referencia

En el shell de Bash, los descriptores de archivo (FD) son importantes para administrar la entrada y salida de los comandos. Muchas personas tienen problemas para comprender correctamente los descriptores de archivos. Cada proceso tiene tres descriptores de archivo predeterminados, a saber:

Ahora que sabe qué hacen los FD predeterminados, veámoslos en acción. Comienzo creando un directorio llamado foo , que contiene file1 .

$> ls foo/ bar/
ls: cannot access 'bar/': No such file or directory
foo/:
file1

La salida No existe tal archivo o directorio va a Error estándar (stderr) y también se muestra en la pantalla. Ejecutaré el mismo comando, pero esta vez usaré 2> para omitir stderr:

$> ls foo/ bar/ 2>/dev/null
foo/:
file1

Es posible enviar la salida de foo a la salida estándar (stdout) y a un archivo simultáneamente e ignore stderr. Por ejemplo:

$> { ls foo bar | tee -a ls_out_file ;} 2>/dev/null
foo:
file1

Entonces:

$> cat ls_out_file
foo:
file1

El siguiente comando envía stdout a un archivo y stderr a /dev/null para que el error no se muestre en la pantalla:

$> ls foo/ bar/ >to_stdout 2>/dev/null
$> cat to_stdout
foo/:
file1

El siguiente comando envía stdout y stderr al mismo archivo:

$> ls foo/ bar/ >mixed_output 2>&1
$> cat mixed_output
ls: cannot access 'bar/': No such file or directory
foo/:
file1

Esto es lo que sucedió en el último ejemplo, donde stdout y stderr fueron redirigidos al mismo archivo:

    ls foo/ bar/ >mixed_output 2>&1
             |          |
             |          Redirect stderr to where stdout is sent
             |                                                        
             stdout is sent to mixed_output

Otro pequeño truco (> Bash 4.4) para enviar stdout y stderr al mismo archivo usa el signo ampersand. Por ejemplo:

$> ls foo/ bar/ &>mixed_output

Aquí hay una redirección más compleja:

exec 3>&1 >write_to_file; echo "Hello World"; exec 1>&3 3>&-

Esto es lo que ocurre:

  • exec 3>&1                      Copiar stdout al descriptor de archivo 3
  • > write_to_file              Hacer FD 1 para escribir en el archivo
  • echo "Hello World"     Ir al archivo porque FD 1 ahora apunta al archivo
  • ejecutivo 1>&3                      Copiar FD 3 de nuevo a 1 (intercambiar)
  • Tres>&-                       Cerrar el descriptor de archivo tres (ya no lo necesitamos)

A menudo, es útil agrupar comandos y luego enviar la salida estándar a un solo archivo. Por ejemplo:

$> { ls non_existing_dir; non_existing_command; echo "Hello world"; } 2> to_stderr
Hello world

Como puede ver, solo se imprime "Hola mundo" en la pantalla, pero la salida de los comandos fallidos se escribe en el archivo to_stderr.

Ejecutar operaciones remotas

Uso Telnet, netcat, Nmap y otras herramientas para probar si un servicio remoto está activo y si puedo conectarme a él. Estas herramientas son útiles, pero no están instaladas de manera predeterminada en todos los sistemas.

Afortunadamente, existe una forma sencilla de probar una conexión sin utilizar herramientas externas. Para ver si un servidor remoto está ejecutando una web, una base de datos, SSH o cualquier otro servicio, ejecute:

$> timeout 3 bash -c ‘</dev/tcp/remote_server/remote_port’ || echo “Failed to connect”

Por ejemplo, para ver si servidorA está ejecutando el servicio MariaDB:

$> timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed to connect”

Si la conexión falla, el mensaje Error al conectar el mensaje se muestra en su pantalla.

Suponga que servidorA está detrás de un cortafuegos/NAT. Quiero ver si el cortafuegos está configurado para permitir una conexión de base de datos a servidorA , pero aún no he instalado un servidor de base de datos. Para emular un puerto de base de datos (o cualquier otro puerto), puedo usar lo siguiente:

[serverA ~]# nc -l 3306

En clienteA , ejecuta:

[clientA ~]# timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed”

Mientras hablo de las conexiones remotas, ¿qué pasa con la ejecución de comandos en un servidor remoto a través de SSH? Puedo usar el siguiente comando:

$> ssh remotehost <<EOF  # Press the Enter key here
> ls /etc
EOF

Este comando ejecuta ls /etc en el host remoto.

También puedo ejecutar una secuencia de comandos local en el host remoto sin tener que copiar la secuencia de comandos en el servidor remoto. Una forma es ingresar:

$> ssh remote_host 'bash -s' < local_script

Otro ejemplo es pasar variables de entorno localmente al servidor remoto y finalizar la sesión después de la ejecución.

$> exec ssh remote_host ARG1=FOO ARG2=BAR 'bash -s' <<'EOF'
> printf %s\\n "$ARG1" "$ARG2"
> EOF
Password:
FOO
BAR
Connection to remote_host closed.

Hay muchas otras acciones complejas que puedo realizar en el host remoto.

Resumir

Ciertamente, hay más en Bash de lo que pude cubrir en esta publicación de blog de dos partes. Estoy compartiendo lo que sé y lo que trato a diario. La idea es familiarizarlo con algunas técnicas que podrían hacer que su trabajo sea menos propenso a errores y más divertido.

[ ¿Quiere poner a prueba sus habilidades de administrador de sistemas? Tome una evaluación de habilidades hoy. ]


Linux
  1. buscar y copiar archivos usando Bash

  2. Extraiga el nombre base del archivo sin ruta y extensión en bash

  3. Función Bash para encontrar el patrón de coincidencia de archivos más nuevo

  4. Cambiar recursivamente las extensiones de archivo en Bash

  5. ¿Qué es exactamente <() en bash (y =() en zsh)?

Encuentre y elimine el archivo más antiguo si hay más de X archivos en un directorio en Linux

Trucos estúpidos de Bash:historial, reutilización de argumentos, archivos y directorios, funciones y más

Complementos, consejos y trucos útiles de Geany

¿Cómo encontrar el tipo de archivo Img y montarlo?

Consejos y trucos de Linux .htaccess

Cómo usar Sed para buscar y reemplazar una cadena en un archivo

    Código Significado Ubicación Descripción
    0 Entrada estándar /dev/stdin Teclado, archivo o alguna secuencia
    1 Salida estándar /dev/stdout Monitor, terminal, pantalla
    2 Error estándar /dev/stderr Los códigos de salida distintos de cero suelen ser>FD2, mostrar