# 103.1 - Trabajar desde la línea de comandos

<table data-header-hidden data-full-width="true"><thead><tr><th width="148"></th><th></th></tr></thead><tbody><tr><td><strong>Importancia</strong></td><td>4</td></tr><tr><td><strong>Descripción</strong></td><td>El candidato debe saber cómo usar la línea de comandos para interactuar con la <em>shell</em> y sus comandos. Se asume el conocimiento de la <em>shell</em> Bash por parte del candidato.</td></tr></tbody></table>

#### *Áreas de conocimiento clave:*

* Usar comandos de *shell* individuales y secuencias de comandos de una línea para realizar tareas básicas en la línea de comandos.
* Usar y modificar el entorno de *shell*, lo que incluye definir, referenciar y exportar variables de entorno.
* Usar y editar el historial de comandos.
* Invocar comandos dentro y fuera de la ruta definida.

### *Contenidos*

### Modos de trabajo

Existen varios modos de trabajo en función de como se usa:

* **GUI**: interfaz gráfica. Por ejemplo, Gnome.
* **CLI**: por comandos de terminal.
  * **Según físico**
    * **TTY**: acceso local a través de consola
    * **PTS**: acceso remoto o indirecto (SSH...)
  * **Según lógico**
    * shell: el programa que entiende los comandos de la máquina. Por ejemplo: bash (estandar de facto), sh, zsh...

Un comando interesante para saber que tipo de CLI se está usando es el comando `who`.

### Rutas

Según como trabajemos con ellas, encontramos dos tipos de rutas de archivos:

* **Rutas absolutas**: desde la raíz, todo el camino para llegar al archivo.&#x20;
  * En Windows por ejemplo, `C:\users\alex\Documentos\archivo.txt`
  * En Linux empiezan siempre con la barra vertical, por ejemplo `/usr/bin/`
* **Rutas relativas**: el camino depende de la ubicación, por ejemplo, si nos encontramos en el directorio `/home/Descargas` podemos acceder directamente al archivo con `./archivo.txt`

Podemos hacer uso de comandos como `whereis` para saber donde esta alojado un servicio o archivo.&#x20;

```bash
whereis ll
whereis fdisk
whereis date
```

Puede ocurrir que no encuentre la ruta del comando pero ello no significa que no exista ese archivo o comando. <mark style="color:red;">Puede ser que no esté buscándolo en el sitio adecuado, o bien que no esté en el</mark> <mark style="color:red;"></mark><mark style="color:red;">`$PATH`</mark>&#x20;

{% hint style="info" %}
En Linux, el `$PATH` es una variable de entorno que especifica una lista de directorios en los cuales el sistema busca los ejecutables cuando se ingresa un comando en la línea de comandos. En resumen, le dice al sistema dónde encontrar los programas que puede ejecutar.
{% endhint %}

Se puede dar el caso que yo en vez de usar el comando "date" puedo escribir la ruta absoluta al archivo y se ejecute también:

```bash
#Cualquiera de estos comandos mostrará la fecha:
date
/bin/date
```

Esto también es aplicable con algunos comandos que presuntamente requiere de sudo pero al añadirlas al `$PATH` se pueden usar sin ello como es el caso de `fdisk`.

Para listar todos los ficheros asociados con comandos puedes aplicar el siguiente bash añadiéndolo a un archivo y ejecutándolo:

{% code title="list\_commands.sh" %}

```bash
for dir in $(echo $PATH | tr ":" "\n"); do
  echo "Archivos en $dir:"
  ls "$dir"
  echo
done
```

{% endcode %}

{% hint style="warning" %}
Cuidado por que **root** tiene su propio entorno y su path.&#x20;

Puedes entrar a **root** con `su root`
{% endhint %}

Puedes visualizar el PATH de forma correcta con el siguiente comando:

```bash
echo $PATH | tr ":" "\n"
```

### Tipos de comandos

De esta forma, probando, llegamos a la conclusión de los tres tipos de comandos de CLI que son:

1. **Comando**: Un comando "normal" es un programa ejecutable almacenado en el sistema de archivos. Estos comandos suelen encontrarse en directorios específicos como `/bin`, `/usr/bin`, `/usr/local/bin`, entre otros. Cuando ejecutas un comando normal, el shell busca el archivo ejecutable correspondiente en los directorios listados en la variable de entorno `$PATH` y lo ejecuta. **Como ejemplos de Comandos:**

   * `ls`: Lista los contenidos de un directorio.
   * `grep`: Busca patrones en archivos.
   * `cat`: Muestra el contenido de un archivo.

2. **Alias**: Un "alias" es una forma abreviada de un comando o una serie de comandos. Los alias permiten crear atajos para comandos largos o complejos, haciendo que sea más fácil y rápido ejecutarlos. Los alias se definen en el shell y son específicos de la sesión actual o de las configuraciones del shell. Para ver los alias definidos **en tu sesión actual**, puedes usar el comandos "`alias`" a secas.

   **->Alias Persistentes**

   Para hacer que un alias sea persistente (es decir, que esté disponible en futuras sesiones), debes añadir la definición del alias al archivo de configuración del shell, como `.bashrc` o `.bash_profile` en el caso de Bash.

3. **Shell builtin:** Es un comando que está integrado directamente en el propio shell. Los builtins son implementados por el shell y no son programas externos. Se ejecutan más rápido que los comandos normales porque no requieren que el shell cree un nuevo proceso. Además, algunos builtins proporcionan funcionalidades esenciales que no se pueden implementar como programas externos. **Como ejemplos de Shell Builtins:**
   * `cd`: Cambia el directorio de trabajo actual.
   * `echo`: Muestra un mensaje en la pantalla.
   * `export`: Establece variables de entorno.
   * `pwd`: Muestra el directorio de trabajo actual (*path workind directory*).
   * `alias`: Define alias.

Se puede revisar que tipo de comando es con "`type`"  o crear un alias con "`alias`" antes del comando:

```bash
alias rm= "rm -i" #Creamos un alias donde te compruebe si quieres borrarlo antes  
```

{% hint style="success" %}
Puedes revisar mas alias útiles en: [#usos-utiles-de-alias](https://apuntes-alex.gitbook.io/apuntes-lpic-1/ejercicios-de-utilidades#usos-utiles-de-alias "mention")
{% endhint %}

<figure><img src="https://727141126-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGDxv9DabSo9OMw53A4vS%2Fuploads%2F2fhFRpy7a7JUrEftgzFh%2Fimage.png?alt=media&#x26;token=257b2850-4ffa-40d3-9cd2-cbac8683456a" alt=""><figcaption><p>Aquí se pueden ver los tres tipos</p></figcaption></figure>

### Obteniendo información

Ya hemos visto conceptos teóricos relacionados con la shell y algunos comandos pero mientras observamos el rectángulo parpadeante de la línea de comandos, la primera pregunta probablemente será “¿Dónde estoy?” O, más precisamente, “¿Dónde estoy en el sistema de archivos de Linux en este momento y si, por ejemplo, he creado un nuevo archivo, ¿Dónde reside?”&#x20;

{% code fullWidth="true" %}

```bash
pwd
# Esto devolverá /home/user vamos a crear un archivo en esta misma ubicación!
touch Frank
ls
# Ahora nos mostrará un nuevo archivo llamado "Frank" y su ubicación completa

#Quizás tambien nos interese saber información general del sistema, para ello:
uname -a
#Esto puede incluir el número exacto de lanzamiento de su distribución o la versión del kernel de Linux cargada.
```

{% endcode %}

Podemos obtener rápidamente datos básicos sobre un comando usando `type`. Este ejemplo usa type para consultar cuatro comandos separados a la vez y ver de que tipo son:&#x20;

```bash
type uname cp kill ll
# uname is hashed (/bin/uname)
# cp is /bin/cp
# kill is a shell builtin
# ll is aliased to 'ls -alF'
```

Los resultados en comentarios nos muestran:

* Que `cp` es un programa que reside en `/bin/cp`
* Que `kill` es un shell incorporado, lo que significa que es en realidad una parte del shell Bash.
* Que `uname` aparece como “hash” lo cual se puede deber a que el usuario recientemente utilizó el comando y, para aumentar la eficiencia del sistema, se agregó a una **tabla hash** para hacer más accesible la próxima vez que se ejecute (Si se ejecutara `type uname` después de un arranque del sistema, encontraríamos que una vez más describe `uname` como un binario regular).
* Que `ll` es un alias del comando ls.

{% hint style="info" %}
Una forma más rápida de limpiar la tabla hash es ejecutar el comando `hash -d <comando>`.
{% endhint %}

### History

El último comando a comentar es `history` que sirve para mostrar  el historial de comandos usados.&#x20;

{% hint style="info" %}
Una buena forma de encontrar un comando en el historial es con `Ctrl+R` que te permite buscar por palabras.

Al pulsar `Ctrl+R` otra vez te guiará por todas las menciones al comando.
{% endhint %}

Hay que tener cuidado por que los datos de `history` no se guardan hasta cerrar sesión, esto podemos verlo haciendo un `ls -A` y buscando el archivo `.bash_history`

<figure><img src="https://727141126-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGDxv9DabSo9OMw53A4vS%2Fuploads%2FVXdsB41cTmqpNIgcXyKe%2Fimage.png?alt=media&#x26;token=8c9f6ff0-e6dc-4acc-be8a-bea0e4029784" alt=""><figcaption><p>Aquí se puede observar los últimos valores del <em>history</em> y los últimos del bash</p></figcaption></figure>

Algunos parámetros interesantes de este comando:

* `history N` donde N es un numero mostrará el comando con ese id
* `history -d N` donde N es el numero de comando que se borrará

A parte, podemos utilizar:

* `! N` ejecutará la instrucción número N
* `!!` ejecutará la última instrucción

### Manual e información de archivos

El comando `man` es el comando que se encarga de mostrar la documentación de otros comandos para ello simplemente se pone delante. De hecho al ser Linux todo ficheros, esa misma documentación la podemos ver en la carpeta del comando (podemos buscar esa carpeta con `whereis` o el propio `ls -l` ), normalmente es `/us/share/man`.

&#x20;       -> Puedes pasar a una sección concreta escribiendo `man 1 ls`&#x20;

No es recomendable pero si quieres leer un archivo del manual sin `man`, puedes descomprimirlo con `gzip -d` y usar `less`:

```bash
zcat /usr/share/man/man1/ls.1.gz | less
```

También existe la versión con el parámetro `--help` y también te puede sacar un abstract del contenido de la documentación  oficial.&#x20;

{% hint style="warning" %}
El poder usar `man` depende de:

* Que el comando sea un comando, no un alias o un shell builtin.

  -> Si quieres usar ayuda con un shell builtin puedes usar el comando `help, por ejemplo help cd`
* Que quien haya programado el software haya dejado el manual hecho, puedes incluso revisar su autoría en el propio manual.
  {% endhint %}

Hay que tener en cuenta que en Linux son todo ficheros y, además, no existen las extensiones, son todo ficheros binarios (`/bin`) y obviamente puedes hacer un `man man` para revisar como usar el comando.

`man` solo funciona cuando se le proporciona un nombre de comando exacto. Sin embargo, si no estamos seguros del nombre del comando que está buscando, podemos usar el comando `apropos` para buscar a través de los nombres y descripciones de la página `man` :

```bash
 apropos kernel
 #Esto nos dará un conjunto de resultados.
```

Podemos revisar además que tipo de archivo son con el comando `file`&#x20;

<figure><img src="https://727141126-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGDxv9DabSo9OMw53A4vS%2Fuploads%2FDvDdOwnxw79Ykcdmg6Fw%2Fimage.png?alt=media&#x26;token=ebbeb9ef-6d64-454e-864b-341cb2ea4e02" alt=""><figcaption><p>Dos archivos diferentes se muestran como texto ASCII</p></figcaption></figure>

Cuando se revisa el **manual** de un comando siempre aparecerá la información de los parámetros que acepta como opciones. Se puede dar el caso que aparezca como:

* **Con corchetes si es un parámetro opcional.**

Por ejemplo, en `ls`, si se ejecuta como tal listara los archivos del directorio actual pero se puede parametrizar para hacer un `ls -l` y listarlos en vertical y detallado o `ls -l /home/Documents` para listar con una ruta absoluta:

<div align="left"><figure><img src="https://727141126-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGDxv9DabSo9OMw53A4vS%2Fuploads%2F51j7vh8I1gyYhYM3QZLj%2Fimage.png?alt=media&#x26;token=512739e0-1f9d-4c72-ba6e-af95d838afcf" alt="" width="350"><figcaption></figcaption></figure></div>

* **Sin corchetes para parámetros obligatorios.**

Por ejemplo, con `mkdir` es obligatorio mencionar el nombre del nuevo directorio con ruta absoluta o relativa.

<div align="left"><figure><img src="https://727141126-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGDxv9DabSo9OMw53A4vS%2Fuploads%2FXdF4VjYIcmjpPIxoma2Y%2Fimage.png?alt=media&#x26;token=a38ea502-b007-4fd7-9caf-090f9fb10402" alt="" width="358"><figcaption></figcaption></figure></div>
