# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

Login Linux: diferencia entre ‘su’ y ‘su -’


su rootYa vimos en otra entrada (/usr/sbin y /sbin no están en $PATH al hacer su) los problemas que nos podía generar hacer login contra un usuario usando únicamente su. Básicamente, la diferencia es que si hacemos su <usuario> a secas “heredaremos” las variables de entorno y lo especificado en los ficheros de inicialización del usuario origen en lugar de recibir los del nuevo. Vamos a ver un ejemplo:

$ whoami
alex
$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/alex/bin
$ su
Contraseña:
# whoami
root
# echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/alex/bin

En el anterior ejemplo, pese a convertirme en root, seguía siendo aplicado el $PATH del usuario anterior (alex). En cambio, si ejecutamos su seguido de un guión y el usuario (para ser root no hace falta especificar el usuario) sí que se leerán los ficheros de inicialización de root y por consiguiente se definirá la variable $PATH correctamente:

$ whoami
alex
$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/alex/bin
$ su -
Contraseña:
# whoami
root
# echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

/usr/sbin y /sbin no están en $PATH al hacer su


Me he encontrado con un problema ante el que el origen parecía un fallo en la variable $PATH que se define al hacer login con un usuario en el sistema. La situación era la siguiente: accedemos por ssh y seguidamente hacemos su para autenticarnos como root. El problema viene en que algunos comandos no se encuentran en el PATH por lo que recibimos errores como estos:

[alex@server  ~$] su
Contraseña:
[root@server alex#] echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/alex/bin

[root@server  ~#] tcpdump
bash: tcpdump: command not found
[root@server   ~#] sendmail
bash: sendmail: command not found

Como podéis ver en la secuencia de comandos, el resultado de la variable $PATH está incompleto, faltan /usr/sbin y /sbin. El correcto sería algo así:

[root@server alex#] echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

Probablemente algunos ya hayáis visto donde está el error, y otros no. El fallo es el paso de la autenticación a root, en lugar de su a secas hay que hacerlo con su -<:

$ su -

La aclaración de esto es que el comportamiento por defecto de su es mantener tanto el directorio home del usuario como sus variables de entorno en lugar de adquirir las del nuevo usuario, en este caso root. Así que si queremos adquirir todas las variables de entorno del usuario contra el que hacemos su deberemos especificar el usuario, o en caso de root el guión por lo menos:

$ su - usuario

Bash y SSH: establecer timeout por inactividad


La variable de entorno TMOUT nos permite definir el tiempo que queremos permitir a un usuario permanecer dentro de la shell o sesión SSH sin hacer nada (estado idle o inactivo). Por defecto no hay límite de tiempo por lo que un usuario podrá permanecer de forma indefinida conectado al sistema independientemente de que la sesión se esté utilizando o no.

Para configurar esta variable, simplemente la añadimos dentro de nuestro perfil de variables/configuraciones de bash ~/.bash_profile o ~/.bashrc. Conviene configurarla como read only para evitar que el propio usuario pueda modificarla:

# Establecemos en 2 minutos (120 segundos) el Timeout para la sesión bash/ssh
TMOUT=120
readonly TMOUT

Refrescamos la shell o entramos y salimos para que sea efectivo:

$ bash

También podemos establecerla a tiempo real mediante export:

$ export TMOUT=120

A partir de ahora, si dejamos la shell abierta durante 2 minutos sin realizar ninguna tarea automáticamente nos desconectará de la sesión:

$ timed out waiting for input: auto-logout

Variables locales y globales en BASH


bashLa shell BASH nos permite utilizar dos tipos de variables, las locales y globales (environment variables). Básicamente, la diferencia entre ambas es que la variable local tiene valor únicamente dentro de nuestra shell, es decir de nuestra sesión. Ningún otro usuario tiene acceso a ella. Por el contrario, las variables globales se establecen para todas las shells., hay que aclarar este último concepto, las variables globales se heredarán desde esta shell a las que se creen a partir de ella (sub-shell o proceso hijo “child” ).

Crear variables locales en bash

Crear una variable local es extremadamente sencillo. En bash por estándar el nombre que asignemos a la variable irá en mayúscula, seguido de un “=” y el valor de la variable, ejemplo:

$ VAR1=prueba_variable_1

La variable ya puede ser usada en cualquier momento desde nuestra shell. A la hora de usar la variable una vez declarada le anteponemos el $, pero no cuando la creamos, ejemplo:

$ echo $VAR1
prueba_variable_1

En todo momento podemos listar las variables establecidas en la shell, para ello ejecutamos el comando

set

:

$ set
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_COMPLETION=/etc/bash_completion
BASH_COMPLETION_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="2" [2]="48" [3]="1" [4]="release" [5]="i486-pc-linux
-gnu")
...
...
...

El listado es muy amplio, así que acotamos la búsqueda a la variable que nos interesa:

$ set | grep ^VAR1
VAR1=prueba_variable_1

Para eliminar la variable utilizamos

unset

seguido del nombre asignado a la variable:

$ unset VAR1

Crear variables de entorno o globales en bash

La sintaxis es distinta, para crear una variable de entorno usaremos

export

seguido de la variable:

$ export VAR2=prueba_variable_2

Al igual que con las variables locales, podemos utilizarla instantáneamente, además en este caso la variable existirá también si abrimos nuevas shells (con el comando bash por ejemplo), mientras que en las variables locales se perdería:

$ echo $VAR2
prueba_variable_2
$ bash
$ echo $VAR2
prueba_variable_2

A la hora de listar las variables de entorno tenemos tres posibilidades, usar

set

como con las locales o

export

o

env

:

$ env | grep ^VAR2
VAR2=prueba_variable_2

$ export | grep VAR2
declare -x VAR2="prueba_variable_2"

$ set | grep ^VAR2
VAR2=prueba_variable_2

Para eliminar la variable hacemos igual que en las locales, unset:

$ unset $VAR2

Normalmente las variables de entorno se definen en el momento que se hace login, a través del fichero .bashrc por ejemplo. Algunas variables de entorno predefinidas en bash son DISPLAY, HOME, PATH, PS1, PWD, SHELL o TERM.

Ignorar alias en bash


Como la mayoría sabéis, los alias en bash sirven para acortar comandos extensos, complicados o muy utilizados a una sola palabra o letra personalizada. Los alias se guardan en $HOME/.bashrc, un ejemplo:

Utilizar la letra ‘l’ para ejecutar ‘ls -ltrh’

alias l='ls -ltrh'

Si quiseramos ignorar temporalmente (durante nuestra sesión) un determinado alias, simplemente debemos ejecutar el comando ‘unalias’, ejemplo:

$ unalias l

Si por otra parte, solamente queremos deshabilitarlo una sola vez (para una ejecución), hay que anteponer al alias la contrabarra.
Por ejemplo, si tenemos configurado el alias siguiente:

alias mv='mv -i'

Podemos ejecutar un comando mv ignorandolo del siguiente modo:

$ \mv

Cómo crear atajos de teclados en Linux (.bashrc)


Cuando trabajar en línea de comandos comienza a ser algo habitual, es extremadamente útil la creación de alias para comandos usados habitualmente, de modo que sea mucho más sencillo y rápido escribirlos en la terminal. El modo de crear atajos de teclado sería el siguiente:

Localizamos el fichero

.bashrc

en nuestra home (en caso de root /root/.bashrc), y localizamos la siguiente sección:

# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'

Esa es la estructura a seguir para la creación de nuevos alias, podemos descomentar los que hay por defecto si nos interesa, o crear nuestros propios, aquí tenéis unos ejemplos:

alias l='ls -ltr'
alias espacio='du -shc'
alias h='history | more'

Una vez introducidos los alias que deseemos, para que funcionen sin tener que salir de la terminal, simplemente ejecutar:

bash

A partir de aquí ya entran las necesidades de cada uno, el objetivo es hacer más sencillo el trabajo diario en la línea de comandos. Tened en cuenta que todo esto sirve para quien trabaje con el intérprete de comandos Bash (intérprete de órdenes estándar de GNU/Linux).