Preguntas y Respuestas para Entrevistas de Shell

ShellBeginner
Practicar Ahora

Introducción

¡Bienvenido a esta guía completa sobre preguntas y respuestas de entrevistas de Shell! Ya sea que te estés preparando para una entrevista, buscando perfeccionar tus habilidades existentes o simplemente tengas curiosidad sobre la amplitud del conocimiento de shell, este documento está diseñado para ser tu recurso definitivo. Cubrimos todo, desde conceptos fundamentales y scripting avanzado hasta la resolución de problemas basada en escenarios y desafíos específicos del rol, asegurando que estés bien equipado para cualquier discusión técnica. Sumérgete para explorar tareas prácticas, técnicas de solución de problemas, mejores prácticas y consideraciones de seguridad esenciales, lo que te permitirá demostrar con confianza tu experiencia en scripting de shell y dominio de la línea de comandos.

SHELL

Conceptos y Comandos Fundamentales de Shell

Respuesta:

Un enlace duro apunta directamente al inode de un archivo, lo que significa que es una entrada de directorio adicional para los mismos datos del archivo. Un enlace blando (symlink) es un archivo especial que contiene una ruta a otro archivo o directorio. Los enlaces duros no pueden abarcar sistemas de archivos y no pueden enlazar a directorios, mientras que los enlaces blandos sí pueden.


Explica el propósito de la variable de entorno PATH.

Respuesta:

La variable de entorno PATH es una lista de directorios separados por dos puntos que el shell busca para encontrar comandos ejecutables cuando se introduce un comando sin su ruta completa. Esto permite a los usuarios ejecutar comandos como ls o grep sin especificar /bin/ls o /usr/bin/grep.


¿Cómo se redirigen la salida estándar y el error estándar a archivos separados?

Respuesta:

Puedes redirigir la salida estándar (1) y el error estándar (2) a archivos separados usando comando > salida.txt 2> error.txt. Esto envía la salida exitosa a salida.txt y los mensajes de error a error.txt.


¿Cuál es la diferencia entre los comandos exec y source (o . )?

Respuesta:

exec reemplaza el proceso del shell actual con el comando especificado, lo que significa que el shell original se termina. source (o .) ejecuta un script en el entorno del shell actual, lo que significa que cualquier variable o función definida en el script se convierte en parte del entorno del shell actual.


Describe la función del comando grep y proporciona un ejemplo básico.

Respuesta:

grep (Global Regular Expression Print) se utiliza para buscar patrones en archivos de texto. Imprime las líneas que coinciden con una expresión regular dada. Por ejemplo, grep 'error' logfile.txt mostrará todas las líneas que contienen la palabra 'error' en logfile.txt.


¿Cómo encontrar todos los archivos de más de 10 MB en el directorio actual y sus subdirectorios?

Respuesta:

Puedes usar el comando find: find . -type f -size +10M. Este comando busca en el directorio actual (.) archivos (-type f) que sean mayores que (+) 10 megabytes (10M).


Explica el concepto de 'piping' (tubería) en el shell.

Respuesta:

El piping (|) es un mecanismo para conectar la salida estándar de un comando a la entrada estándar de otro comando. Esto permite encadenar múltiples comandos para realizar operaciones complejas, donde la salida de un comando se convierte en la entrada para el siguiente.


¿Cuál es la importancia del carácter ~ (tilde) en el shell?

Respuesta:

El carácter ~ (tilde) es una notación abreviada que se expande al directorio de inicio del usuario actual. Por ejemplo, cd ~/documents cambiará el directorio a la carpeta documents dentro del directorio de inicio del usuario.


¿Cómo ver el contenido de un archivo comprimido con gzipped sin descomprimirlo?

Respuesta:

Puedes usar el comando zcat. Por ejemplo, zcat file.gz mostrará el contenido descomprimido de file.gz a la salida estándar sin crear un archivo descomprimido en el disco.


¿Cuál es el propósito del comando chmod?

Respuesta:

chmod (change mode) se utiliza para cambiar los permisos de archivos y directorios. Controla quién puede leer, escribir o ejecutar un archivo. Los permisos se pueden establecer usando modos simbólicos (por ejemplo, u+x) o notación octal (por ejemplo, 755).


Scripting y Programación Avanzada

Explica la diferencia entre 'source' y ejecutar un script directamente (por ejemplo, './script.sh').

Respuesta:

Hacer "source" de un script (source script.sh o . script.sh) lo ejecuta en el entorno del shell actual, lo que significa que cualquier variable o función definida se convierte en parte del shell actual. Ejecutarlo directamente (./script.sh) ejecuta el script en un nuevo subshell, por lo que los cambios en el entorno no se propagan de vuelta al shell padre.


¿Cómo se manejan los errores y los códigos de salida en un script de shell?

Respuesta:

Los errores se manejan típicamente comprobando el estado de salida de los comandos usando $?. Un estado de salida distinto de cero indica un error. Puedes usar set -e para salir inmediatamente si un comando falla, o trap para ejecutar un comando al salir o ante señales específicas.


Describe el propósito de 'set -euxo pipefail' al principio de un script.

Respuesta:

set -e sale inmediatamente si un comando termina con un estado distinto de cero. set -u trata las variables no definidas como errores. set -x imprime los comandos y sus argumentos a medida que se ejecutan. set -o pipefail hace que una tubería (pipeline) devuelva el estado de salida del último comando que devolvió un estado distinto de cero, en lugar de solo el último comando en la tubería.


¿Cómo puedes pasar argumentos a un script de shell y acceder a ellos?

Respuesta:

Los argumentos se pasan directamente después del nombre del script (por ejemplo, ./script.sh arg1 arg2). Dentro del script, se accede a ellos usando parámetros posicionales: $1 para el primer argumento, $2 para el segundo, y así sucesivamente. $# da el número total de argumentos, y $@ se expande a todos los argumentos como palabras separadas.


Explica el concepto de 'here documents' (documentos aquí) y proporciona un ejemplo sencillo.

Respuesta:

Un 'here document' te permite alimentar múltiples líneas de entrada a un comando como si se hubieran escrito en el teclado, sin crear un archivo temporal. Se denota con << DELIMITER. Ejemplo: cat << EOF Hello World EOF.


¿Qué es un comando 'trap' y cuándo lo usarías?

Respuesta:

El comando trap te permite ejecutar un comando cuando el shell recibe una señal (por ejemplo, SIGINT para Ctrl+C, SIGTERM para terminación) o cuando el shell sale. Se usa comúnmente para operaciones de limpieza, como eliminar archivos temporales, asegurando que los recursos se liberen incluso si el script se interrumpe.


¿Cómo se realizan operaciones aritméticas en Bash?

Respuesta:

Las operaciones aritméticas en Bash se realizan típicamente usando ((...)) o $[...]. Por ejemplo, result=$((5 + 3)) o result=$[5 + 3]. El comando expr también se puede usar, pero es más antiguo y menos eficiente para aritmética entera simple.


Describe cómo depurar un script de shell.

Respuesta:

La depuración se puede hacer añadiendo set -x al principio del script o ejecutando bash -x script.sh. Esto imprime cada comando antes de que se ejecute. También puedes insertar sentencias echo para imprimir los valores de las variables en diferentes etapas de la ejecución.


¿Cuál es la diferencia entre [[ y [ para expresiones condicionales?

Respuesta:

[[ es una palabra clave de Bash que ofrece características más avanzadas que [ (que es un comando externo) compatible con POSIX. [[ soporta la coincidencia de patrones (=~), operadores lógicos (&&, ||), y evita la división de palabras y la expansión de nombres de ruta, lo que lo hace más seguro y potente para pruebas de cadenas y archivos.


¿Cómo escribirías una función en Bash y cómo la llamarías?

Respuesta:

Las funciones se definen usando nombre_funcion() { comandos; } o function nombre_funcion { comandos; }. Se llaman simplemente escribiendo su nombre. Los argumentos se pasan a las funciones igual que a los scripts, usando parámetros posicionales ($1, $2, etc.) dentro del ámbito de la función. Ejemplo: mi_func() { echo $1; }; mi_func 'hola'.


Scenario-Based Problem Solving

You need to find all files larger than 10MB in the current directory and its subdirectories, then list their paths and sizes in a human-readable format. How would you do this?

Answer:

Use find . -type f -size +10M -exec du -h {} \;. find locates files, -type f specifies files, -size +10M filters by size, and -exec du -h {} \; executes du -h for each found file.


A log file /var/log/app.log is growing rapidly. You need to extract all lines containing the word 'ERROR' from the last 24 hours and save them to a new file errors_today.log. Assume log entries start with a timestamp.

Answer:

First, determine the timestamp for 24 hours ago. Then, use grep with awk or sed to filter. Example: grep 'ERROR' /var/log/app.log | awk '$1 >= "$(date -d '24 hours ago' +'%Y-%m-%d')"' > errors_today.log. A more robust solution might involve logrotate or journalctl if available.


You have a CSV file data.csv with columns Name,Age,City. You need to sort it by Age in descending order and then by Name in ascending order, outputting only Name and City.

Answer:

Use sort with cut and awk. (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1n) to sort. Then cut -d',' -f1,3 or awk -F',' '{print $1 "," $3}' to select columns. Combining: (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1) | awk -F',' '{print $1 "," $3}'.


A script myscript.sh is running in the background, but you suspect it's stuck. How would you check its status, and if it's unresponsive, how would you terminate it gracefully, then forcefully if necessary?

Answer:

Check status with ps aux | grep myscript.sh. To gracefully terminate, use kill <PID>. If it doesn't respond, use kill -9 <PID> for a forceful termination. Always try graceful termination first to allow cleanup.


You need to create a backup of the /etc directory, compress it using gzip, and store it in /tmp/etc_backup_YYYYMMDD.tar.gz. How would you automate this?

Answer:

Use tar with gzip. tar -czf /tmp/etc_backup_$(date +%Y%m%d).tar.gz /etc. This command creates a gzipped tar archive (-c create, -z gzip, -f filename) with a date-stamped name.


You're troubleshooting a network issue. How would you check if a specific port (e.g., 8080) is open and listening on your local machine, and what process is using it?

Answer:

Use netstat -tulnp | grep :8080 or lsof -i :8080. netstat shows network connections, -t TCP, -u UDP, -l listening, -n numeric, -p process ID. lsof lists open files, including network sockets.


You need to download a file from a URL (http://example.com/file.zip) and save it as downloaded_file.zip in the current directory. How would you do this using a command-line tool?

Answer:

Use wget or curl. With wget: wget -O downloaded_file.zip http://example.com/file.zip. With curl: curl -o downloaded_file.zip http://example.com/file.zip. Both tools are common for HTTP/HTTPS downloads.


You have a directory with many files, and you need to rename all files ending with .txt to end with .log instead. How would you accomplish this?

Answer:

Use a for loop with mv. for f in *.txt; do mv "$f" "${f%.txt}.log"; done. The "${f%.txt}.log" syntax removes the .txt suffix and appends .log.


You need to find the top 5 largest files in the /var directory, excluding subdirectories like /var/cache and /var/log.

Answer:

Use du and sort. du -ah --exclude=/var/cache --exclude=/var/log /var | sort -rh | head -n 5. du -ah lists sizes in human-readable format, sort -rh sorts numerically in reverse, and head -n 5 gets the top 5.


A script needs to run every day at 3 AM. How would you schedule this task?

Answer:

Use cron. Add an entry to the crontab: 0 3 * * * /path/to/your/script.sh. This means at minute 0, hour 3, every day of the month, every month, and every day of the week, execute the script.


Solución de Problemas Basada en Escenarios

Necesitas encontrar todos los archivos de más de 10 MB en el directorio actual y sus subdirectorios, luego listar sus rutas y tamaños en un formato legible para humanos. ¿Cómo lo harías?

Respuesta:

Usa find . -type f -size +10M -exec du -h {} \;. find localiza archivos, -type f especifica archivos, -size +10M filtra por tamaño, y -exec du -h {} \; ejecuta du -h para cada archivo encontrado.


Un archivo de log /var/log/app.log está creciendo rápidamente. Necesitas extraer todas las líneas que contienen la palabra 'ERROR' de las últimas 24 horas y guardarlas en un nuevo archivo errors_today.log. Asume que las entradas del log comienzan con una marca de tiempo.

Respuesta:

Primero, determina la marca de tiempo de hace 24 horas. Luego, usa grep con awk o sed para filtrar. Ejemplo: grep 'ERROR' /var/log/app.log | awk '$1 >= "$(date -d '24 hours ago' +'%Y-%m-%d')"' > errors_today.log. Una solución más robusta podría implicar logrotate o journalctl si están disponibles.


Tienes un archivo CSV data.csv con las columnas Name,Age,City. Necesitas ordenarlo por Age en orden descendente y luego por Name en orden ascendente, mostrando solo Name y City.

Respuesta:

Usa sort con cut y awk. (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1n) para ordenar. Luego cut -d',' -f1,3 o awk -F',' '{print $1 "," $3}' para seleccionar columnas. Combinando: (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1) | awk -F',' '{print $1 "," $3}'.


Un script myscript.sh se está ejecutando en segundo plano, pero sospechas que está atascado. ¿Cómo verificarías su estado y, si no responde, cómo lo terminarías de forma controlada y luego forzada si fuera necesario?

Respuesta:

Verifica el estado con ps aux | grep myscript.sh. Para terminar de forma controlada, usa kill <PID>. Si no responde, usa kill -9 <PID> para una terminación forzada. Siempre intenta primero la terminación controlada para permitir la limpieza.


Necesitas crear una copia de seguridad del directorio /etc, comprimirla usando gzip, y almacenarla en /tmp/etc_backup_YYYYMMDD.tar.gz. ¿Cómo automatizarías esto?

Respuesta:

Usa tar con gzip. tar -czf /tmp/etc_backup_$(date +%Y%m%d).tar.gz /etc. Este comando crea un archivo tar comprimido con gzip (-c crear, -z gzip, -f nombre de archivo) con un nombre que incluye la fecha.


Estás solucionando un problema de red. ¿Cómo verificarías si un puerto específico (por ejemplo, 8080) está abierto y escuchando en tu máquina local, y qué proceso lo está utilizando?

Respuesta:

Usa netstat -tulnp | grep :8080 o lsof -i :8080. netstat muestra conexiones de red, -t TCP, -u UDP, -l escuchando, -n numérico, -p ID del proceso. lsof lista archivos abiertos, incluyendo sockets de red.


Necesitas descargar un archivo de una URL (http://example.com/file.zip) y guardarlo como downloaded_file.zip en el directorio actual. ¿Cómo lo harías usando una herramienta de línea de comandos?

Respuesta:

Usa wget o curl. Con wget: wget -O downloaded_file.zip http://example.com/file.zip. Con curl: curl -o downloaded_file.zip http://example.com/file.zip. Ambas herramientas son comunes para descargas HTTP/HTTPS.


Tienes un directorio con muchos archivos, y necesitas renombrar todos los archivos que terminan en .txt para que terminen en .log en su lugar. ¿Cómo lograrías esto?

Respuesta:

Usa un bucle for con mv. for f in *.txt; do mv "$f" "${f%.txt}.log"; done. La sintaxis "${f%.txt}.log" elimina el sufijo .txt y añade .log.


Necesitas encontrar los 5 archivos más grandes en el directorio /var, excluyendo subdirectorios como /var/cache y /var/log.

Respuesta:

Usa du y sort. du -ah --exclude=/var/cache --exclude=/var/log /var | sort -rh | head -n 5. du -ah lista los tamaños en formato legible para humanos, sort -rh ordena numéricamente en orden inverso, y head -n 5 obtiene los 5 principales.


Un script necesita ejecutarse todos los días a las 3 AM. ¿Cómo programarías esta tarea?

Respuesta:

Usa cron. Añade una entrada al crontab: 0 3 * * * /ruta/a/tu/script.sh. Esto significa a las 0 minutos, hora 3, todos los días del mes, todos los meses y todos los días de la semana, ejecuta el script.


Tareas Prácticas y de Scripting

Escribe un script de shell que tome la ruta de un directorio como argumento y cuente el número de archivos regulares y subdirectorios dentro de él. Maneja los casos en que el directorio no existe.

Respuesta:

#!/bin/bash
DIR="$1"
if [ ! -d "$DIR" ]; then
  echo "Error: Directorio '$DIR' no encontrado."
  exit 1
fi
files=$(find "$DIR" -maxdepth 1 -type f | wc -l)
dirs=$(find "$DIR" -maxdepth 1 -type d | wc -l)
## Resta 1 de dirs por el propio directorio
echo "Archivos: $files, Directorios: $((dirs - 1))"

¿Cómo encontrarías todos los archivos de más de 10 MB en el directorio actual y sus subdirectorios, y luego listarlos ordenados por tamaño?

Respuesta:

Usa find . -type f -size +10M -print0 | xargs -0 du -h | sort -rh. find localiza archivos, -print0 y xargs -0 manejan caracteres especiales, du -h obtiene tamaños legibles para humanos, y sort -rh ordena por tamaño en orden inverso legible para humanos.


Escribe una línea de comando para reemplazar todas las ocurrencias de 'foo' por 'bar' en todos los archivos .txt del directorio actual.

Respuesta:

find . -maxdepth 1 -type f -name "*.txt" -exec sed -i 's/foo/bar/g' {} \;

Esto usa find para localizar archivos .txt y sed -i para el reemplazo en el lugar. Alternativamente, grep -lR foo *.txt | xargs sed -i 's/foo/bar/g'.


Explica la diferencia entre $$ y $! en scripting de shell.

Respuesta:

$$ se expande al ID de proceso (PID) del shell actual. $! se expande al PID del comando en segundo plano (asíncrono) ejecutado más recientemente. Son útiles para crear archivos temporales únicos o gestionar procesos en segundo plano.


¿Cómo se analizan los argumentos de la línea de comandos en un script de shell, específicamente argumentos con nombre como --file <ruta> o -v?

Respuesta:

Usa getopts para opciones cortas (-v) o un bucle while getopts. Para opciones largas (--file), un bucle while true; do case "$1" in ... esac; shift; done con sentencias case es común, a menudo combinado con shift para consumir argumentos.


Escribe un script que monitoree un archivo de log (/var/log/syslog por ejemplo) e imprima las nuevas líneas a medida que se agregan, similar a tail -f.

Respuesta:

#!/bin/bash
tail -f /var/log/syslog

Esto aprovecha directamente el comando tail -f, que está diseñado para este propósito. Para un enfoque más manual, se podría usar inotifywait o un bucle con wc -l y sed.


¿Cómo te asegurarías de que un script de shell salga inmediatamente si algún comando falla?

Respuesta:

Añade set -e al principio del script. Esta opción hace que el shell salga inmediatamente si un comando termina con un estado distinto de cero. Es crucial para una ejecución de script robusta.


Tienes un archivo CSV data.csv con las columnas Name,Age,City. ¿Cómo extraerías solo las columnas Name y City usando herramientas estándar de shell?

Respuesta:

cut -d',' -f1,3 data.csv

Esto usa cut con un delimitador de coma (-d',') para seleccionar el primer y tercer campo (-f1,3). Alternativamente, awk -F',' '{print $1 "," $3}' data.csv puede lograr lo mismo.


Escribe una función en un script de shell que tome dos números como argumentos y devuelva su suma.

Respuesta:

#!/bin/bash
sum_numbers() {
  echo $(($1 + $2))
}
result=$(sum_numbers 10 5)
echo "Suma: $result"

Las funciones se definen con nombre_funcion() { ... }. La expansión aritmética $((...)) se usa para cálculos. El resultado generalmente se imprime y se captura mediante sustitución de comandos.


¿Cómo programarías un script para que se ejecute todos los días a las 3 AM?

Respuesta:

Usa cron. Añade una entrada al archivo crontab (crontab -e) como 0 3 * * * /ruta/a/tu_script.sh. Los campos representan minuto, hora, día del mes, mes y día de la semana, respectivamente.


Solución de Problemas y Depuración de Scripts de Shell

Mejores Prácticas y Optimización de Rendimiento en Shell

¿Cómo se puede optimizar un script de shell para el rendimiento al tratar con archivos grandes o muchas iteraciones?

Respuesta:

Evita bifurcaciones (forks) innecesarias (por ejemplo, usar grep dentro de un bucle). Utiliza las características integradas del shell siempre que sea posible (por ejemplo, expansión de parámetros en lugar de sed). Procesa datos en fragmentos o usa awk para un procesamiento eficiente línea por línea.


Explica la diferencia entre $(comando) y `comando` para la sustitución de comandos y cuál se prefiere como mejor práctica.

Respuesta:

$(comando) es la sintaxis moderna y preferida. Maneja la anidación con más facilidad y evita problemas con barras invertidas y comillas que pueden ocurrir con las comillas invertidas (`comando`). $(comando) es generalmente más legible y robusto.


¿Cuál es el propósito de set -e y set -u en un script de shell, y por qué se consideran buenas prácticas?

Respuesta:

set -e (errexit) hace que el script salga inmediatamente si un comando termina con un estado distinto de cero. set -u (nounset) trata las variables no establecidas como un error y sale. Ambas mejoran la robustez del script al detectar errores temprano y prevenir comportamientos inesperados.


¿Cómo se puede prevenir el 'globbing' o la expansión de nombres de ruta en un script de shell?

Respuesta:

Para prevenir el globbing, encierra la cadena entre comillas dobles. Por ejemplo, ls "*.txt" tratará *.txt como una cadena literal, mientras que ls *.txt se expandirá a todos los archivos .txt en el directorio actual.


¿Cuándo se debe usar [[ ... ]] en lugar de [ ... ] para expresiones condicionales en Bash?

Respuesta:

[[ ... ]] es una palabra clave específica de Bash que ofrece más características que el comando [ ... ] compatible con POSIX. Admite la coincidencia de patrones (=~), operadores lógicos (&&, ||), y evita la división de palabras y la expansión de nombres de ruta, lo que la hace más segura y potente.


Describe un escenario donde usar xargs sería más eficiente que un bucle for.

Respuesta:

xargs es más eficiente al procesar una gran lista de elementos como argumentos para un comando. Construye líneas de comando con múltiples argumentos, reduciendo el número de veces que se invoca el comando de destino, a diferencia de un bucle for que típicamente llama al comando una vez por elemento.


¿Cuál es la importancia de redirigir stderr a /dev/null (por ejemplo, 2>/dev/null)?

Respuesta:

Redirigir stderr a /dev/null descarta los mensajes de error, evitando que se muestren en la consola o contaminen la salida. Esto es útil para suprimir errores esperados o cuando solo te importa stdout.


¿Cómo se puede hacer que un script de shell sea más portable entre diferentes sistemas tipo Unix?

Respuesta:

Utiliza comandos y características compatibles con POSIX siempre que sea posible. Evita extensiones específicas de Bash como [[ ... ]] o la sustitución de procesos si se requiere portabilidad estricta. Especifica explícitamente el intérprete usando un shebang como #!/bin/sh.


¿Por qué generalmente es una mala práctica analizar la salida de ls en scripts de shell?

Respuesta:

Analizar la salida de ls es problemático porque los nombres de archivo pueden contener espacios, saltos de línea o caracteres especiales, lo que puede romper la lógica del script cuando es procesado por herramientas como awk o bucles for. Usa find -print0 | xargs -0 para un manejo seguro de nombres de archivo.


¿Cuál es el propósito de trap en scripting de shell y proporciona un ejemplo simple.

Respuesta:

trap te permite ejecutar comandos cuando el shell recibe una señal (por ejemplo, EXIT, INT, TERM). Es crucial para operaciones de limpieza. Ejemplo: trap 'rm -f /tmp/mytempfile' EXIT asegura que un archivo temporal se elimine cuando el script finaliza.


Control de Versiones y Colaboración con Shell

¿Cómo usas típicamente Git desde la línea de comandos para tareas de desarrollo diarias?

Respuesta:

Principalmente uso git status, git add, git commit -m "mensaje", git pull y git push. Para ramificación (branching), uso git checkout -b nombre-rama y git merge o git rebase.


Explica la diferencia entre git pull y git fetch.

Respuesta:

git fetch descarga nuevos datos de un repositorio remoto pero no los integra en tus archivos de trabajo. git pull es esencialmente git fetch seguido de git merge (o git rebase, dependiendo de la configuración), integrando los cambios en tu rama actual.


¿Cómo revertirías un commit específico que ya ha sido enviado a un repositorio remoto?

Respuesta:

Usaría git revert <hash-del-commit>. Esto crea un nuevo commit que deshace los cambios del commit especificado, preservando el historial del proyecto. Es más seguro que git reset --hard para ramas compartidas.


Describe un escenario donde usarías git rebase en lugar de git merge.

Respuesta:

Usaría git rebase para mantener un historial de proyecto limpio y lineal, especialmente en ramas de características antes de fusionarlas en main. Reaplica commits de una rama sobre otra, evitando commits de fusión y haciendo que el historial sea más fácil de leer.


¿Cómo resuelves conflictos de fusión usando la línea de comandos?

Respuesta:

Después de un conflicto de fusión, git status muestra los archivos en conflicto. Edito manualmente estos archivos para resolver los conflictos, luego uso git add <archivo-en-conflicto> para marcarlos como resueltos. Finalmente, completo la fusión con git commit.


¿Qué es git stash y cuándo lo usarías?

Respuesta:

git stash guarda temporalmente los cambios que no están listos para ser confirmados (committed), permitiéndote cambiar de rama o realizar otras tareas. Es útil cuando necesitas cambiar de contexto rápidamente sin confirmar trabajo incompleto.


¿Cómo puedes ver el historial de commits de un archivo específico?

Respuesta:

Uso git log -- <ruta-del-archivo>. Este comando muestra todos los commits que han afectado al archivo especificado, incluyendo el hash del commit, autor, fecha y mensaje del commit.


Comprobaste accidentalmente información sensible. ¿Cómo la eliminas de tu historial de Git?

Respuesta:

Para commits recientes no enviados, git reset HEAD~1 seguido de la modificación del commit es una opción. Para commits enviados o historial más profundo, se usan git filter-branch o BFG Repo-Cleaner para reescribir el historial, pero esto es disruptivo y requiere un force-push.


Explica el propósito de un archivo .gitignore.

Respuesta:

Un archivo .gitignore especifica archivos intencionalmente no rastreados que Git debe ignorar. Esto evita que archivos temporales, artefactos de compilación o archivos de configuración sensibles sean confirmados accidentalmente en el repositorio.


¿Cómo creas y cambias a una nueva rama en Git?

Respuesta:

Para crear y cambiar a una nueva rama, uso git checkout -b nombre-nueva-rama. Este comando es un atajo para git branch nombre-nueva-rama seguido de git checkout nombre-nueva-rama.


Consideraciones de Seguridad en Scripting de Shell

¿Por qué es peligroso ejecutar scripts de shell descargados de fuentes no confiables?

Respuesta:

Los scripts no confiables pueden contener código malicioso que podría eliminar archivos, instalar malware, robar datos sensibles o crear puertas traseras. Se ejecutan con los permisos del usuario que los ejecuta, lo que los convierte en un riesgo de seguridad significativo.


¿Cómo se pueden prevenir las vulnerabilidades de inyección de comandos en scripts de shell?

Respuesta:

Siempre entrecomilla las variables que contienen entrada del usuario, especialmente cuando se usan en comandos. Usa set -e y set -u para detectar errores y variables no establecidas. Evita eval con entrada no confiable. Prefiere comandos específicos sobre los generales y valida la entrada rigurosamente.


Explica la importancia de la validación de entrada en scripting de shell para la seguridad.

Respuesta:

La validación de entrada asegura que los datos proporcionados a un script se ajusten a los formatos y valores esperados, evitando que se procese entrada maliciosa. Esto mitiga riesgos como la inyección de comandos, el recorrido de directorios (path traversal) y los desbordamientos de búfer al rechazar caracteres inválidos o peligrosos.


¿Cuáles son los riesgos de usar eval en scripts de shell y cuándo podría ser aceptable?

Respuesta:

eval ejecuta sus argumentos como comandos de shell, lo que lo hace muy susceptible a la inyección de comandos si se usa con entrada no confiable. Generalmente es aceptable solo cuando la entrada está completamente controlada y confiada por el propio script, o cuando se construyen dinámicamente comandos simples y seguros.


¿Cómo se puede manejar de forma segura información sensible como contraseñas o claves de API en scripts de shell?

Respuesta:

Evita codificar datos sensibles directamente en los scripts. En su lugar, utiliza variables de entorno (con precaución), archivos de configuración seguros con permisos restringidos, o herramientas dedicadas de gestión de secretos como HashiCorp Vault o AWS Secrets Manager. Nunca los almacenes en el control de versiones.


¿Por qué es importante establecer permisos de archivo apropiados para los scripts de shell y sus archivos de salida?

Respuesta:

Los permisos de archivo incorrectos pueden permitir que usuarios no autorizados lean, modifiquen o ejecuten scripts o sus salidas. Los scripts típicamente solo deberían ser ejecutables por su propietario, y los archivos de salida sensibles deberían tener permisos de lectura/escritura restrictivos para prevenir fugas de datos o manipulaciones.


¿Cuál es el propósito de set -u (o set -o nounset) en un script de shell para la seguridad?

Respuesta:

set -u hace que el script salga inmediatamente si intenta usar una variable no establecida. Esto previene comportamientos inesperados o vulnerabilidades de seguridad que podrían surgir de una variable no inicializada que se interpreta como una cadena vacía o un valor predeterminado, lo que podría llevar a la ejecución de comandos o operaciones de archivo no intencionadas.


Describe el concepto de 'mínimo privilegio' en el contexto de la ejecución de scripts de shell.

Respuesta:

El principio de mínimo privilegio dicta que un script debe ejecutarse con los permisos mínimos necesarios para realizar su función prevista. Esto limita el daño potencial si el script se ve comprometido, ya que no tendrá acceso elevado a sistemas o datos que no necesita.


¿Cómo puede la manipulación de rutas (path manipulation) conducir a vulnerabilidades de seguridad en scripts de shell?

Respuesta:

Si la variable de entorno PATH no se controla cuidadosamente, un usuario malintencionado podría inyectar su propio directorio que contenga un ejecutable con un nombre similar (por ejemplo, ls o rm). Cuando el script llama a ese comando, podría ejecutar la versión maliciosa en lugar de la legítima, lo que llevaría a acciones no deseadas.


¿Cuáles son algunas de las mejores prácticas para escribir scripts de shell seguros?

Respuesta:

Valida toda la entrada del usuario, entrecomilla las variables, usa set -euo pipefail, evita eval con datos no confiables, establece permisos de archivo restrictivos, usa rutas absolutas para los comandos y sigue el principio de mínimo privilegio. Audita regularmente los scripts en busca de vulnerabilidades y mantenlos actualizados.


Resumen

Una preparación exhaustiva es fundamental para el éxito en el riguroso proceso de entrevistas de Shell. Al revisar diligentemente las preguntas comunes, comprender los valores de Shell y practicar tus respuestas, mejoras significativamente tus posibilidades de mostrar tus capacidades y tu idoneidad para el puesto. Este documento sirve como un recurso valioso para guiar tu preparación, ayudándote a anticipar posibles consultas y a formular respuestas convincentes.

Recuerda, el viaje no termina con la entrevista. La industria energética es dinámica y el aprendizaje continuo es clave para el crecimiento profesional. Aprovecha cada oportunidad para ampliar tus conocimientos y habilidades, asegurándote de seguir siendo un activo valioso en un panorama en constante evolución. Tu dedicación a la preparación y al aprendizaje permanente sin duda allanará el camino hacia una carrera gratificante.