Scripts en /etc/profile.d ¿Ignorado?

61

Soy nuevo en Ubuntu. Estoy ejecutando 13.10 Desktop.

Quería establecer algunos alias de todo el sistema y un mensaje personalizado para bash. Encontré este artículo:

https://help.ubuntu.com/community/EnvironmentVariables

Siguiendo los consejos de este artículo, creé /etc/profiles.d/profile_local.sh. Es propiedad de root y tiene permisos de 644 al igual que los otros scripts allí:

root@ubuntu:/etc/profile.d# ll
total 28
drwxr-xr-x   2 root root  4096 Mar 23 08:56 .
drwxr-xr-x 135 root root 12288 Mar 23 09:15 ..
-rw-r--r--   1 root root   660 Oct 23  2012 bash_completion.sh
-rw-r--r--   1 root root  3317 Mar 23 07:36 profile_local.sh
-rw-r--r--   1 root root  1947 Nov 23 00:57 vte.sh

Además, he confirmado que / etc / profile llama a /etc/profile.d. Contiene este bloque de código:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Al iniciar sesión, no parece que se obtenga el script personalizado, profile_local.sh que creé. Sin embargo, si después de iniciar sesión, 'source /etc.profile.d/profile_local.sh', obtengo el comportamiento esperado, mis alias personalizados y un mensaje personalizado.

¿Qué estoy haciendo mal?

Contenido del script 'profile_local.sh':

# 3/23/14 - Copied from Gentoo /etc/bash/bashrc
# Placed in /etc/profile.d as described at:
# https://help.ubuntu.com/community/EnvironmentVariables

# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !


# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
        # Shell is non-interactive.  Be done now!
        return
fi

# Bash won't get SIGWINCH if another process is in the foreground.
# Enable checkwinsize so that bash will check the terminal size when
# it regains control.  #65623
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
shopt -s checkwinsize

# Enable history appending instead of overwriting.  #139609
shopt -s histappend

# Change the window title of X terminals 
case ${TERM} in
        xterm*|rxvt*|Eterm|aterm|kterm|gnome*|interix)
                PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                ;;
        screen)
                PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
                ;;
esac

use_color=false

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
        && type -P dircolors >/dev/null \
        && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
        # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
        if type -P dircolors >/dev/null ; then
                if [[ -f ~/.dir_colors ]] ; then
                        eval $(dircolors -b ~/.dir_colors)
                elif [[ -f /etc/DIR_COLORS ]] ; then
                        eval $(dircolors -b /etc/DIR_COLORS)
                fi
        fi

        if [[ ${EUID} == 0 ]] ; then
                PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
        else
                PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
        fi

        alias ls='ls --color=auto'
        alias grep='grep --colour=auto'
else
        if [[ ${EUID} == 0 ]] ; then
                # show root@ when we don't have colors
                PS1='\u@\h \W \$ '
        else
                PS1='\u@\h \w \$ '
        fi
fi

# Try to keep environment pollution down, EPA loves us.
unset use_color safe_term match_lhs

TZ="PST8PDT"

alias ll='ls -la'
alias dig='dig +search'
alias dir='ls -ba'

alias edit="ee"
alias ss="ps -aux"
alias dot='ls .[a-zA-Z0-9_]*'
alias news="xterm -g 80x45 -e trn -e -S1 -N &"

alias more="less"
alias c="clear"
alias m="more"
alias j="jobs"

# common misspellings
alias mroe=more
alias pdw=pwd
Dibujó
fuente
1
No, no es ejecutable, pero tampoco lo son los otros dos scripts. Sin embargo, lo cambié e intenté nuevamente. Aún sin suerte.
Drew
3
Esto no tiene nada que ver con agregar .sh, es irrelevante y, de todos modos, los archivos profile.dprovienen, no se ejecutan, lo que es ligeramente diferente y no requiere que el archivo sea ejecutable. El problema aquí es que profile& co no son leídos por scripts que no inician sesión.
terdon
1
Drew, lee mi respuesta. Los shells que no inician sesión ignoran los archivos de perfil, pero el inicio de sesión predeterminado de la GUI de Ubuntu leerá algunos de ellos. Simplemente use .bashrcy todos sus problemas desaparecerán. También hay una cuestión de precedencia, si uno de los archivos que se leen posteriormente también establece PS1, entonces el valor anterior será descartado. De todos modos, en serio, no toque los archivadores /etc, juegue con los del directorio de inicio y .bashrcno use el perfil.
terdon
1
Sí, eso debería ser un shell de inicio de sesión (ese es el tipo de cosa que debería incluir en su pregunta la próxima vez). Sin embargo, la mayoría de los sistemas tienen .profilearchivos predeterminados en su hogar y la configuración allí sobrescribirá todo lo que haga /etc/profile. Básicamente, nunca toque a /etcmenos que sepa lo que está haciendo. Para eso están los archivos específicos del usuario. Además, edite su pregunta y explique exactamente cómo se está conectando, eso lo cambia todo.
terdon
44
No hagas esto usando /etc/profile.dque es una muy mala idea y afectará a todos los usuarios del sistema. Basta con incluir los comandos de profile_local.shen su ~/.profileo, simplemente, la fuente de la secuencia de comandos mediante la adición de esta línea a su ~/.profile: . /path/to/profile_local.sh. (el .medio source, leerá el archivo que le dé y ejecutará los comandos que encuentre allí).
terdon

Respuestas:

109

Para comprender lo que está sucediendo aquí, debe comprender un poco de información básica sobre cómo se ejecutan los shells (bash en este caso).

  • Cuando abre un emulador de terminal ( gnome-terminalpor ejemplo), está ejecutando lo que se conoce como un shell interactivo sin inicio de sesión .

  • Cuando inicia sesión en su máquina desde la línea de comandos, mediante ssho ejecuta un comando como su - username, está ejecutando un shell de inicio de sesión interactivo .

  • Cuando inicia sesión gráficamente, está ejecutando algo completamente diferente, los detalles dependerán de su sistema y entorno gráfico, pero en general es el shell gráfico el que se ocupa de su inicio de sesión. Si bien muchos shells gráficos (incluido el predeterminado de Ubuntu) leerán, /etc/profileno todos lo harán.

  • Finalmente, cuando ejecuta un script de shell, se ejecuta en un shell no interactivo y sin inicio de sesión .

Ahora, los archivos que bash leerá cuando se inicien dependen del tipo de shell en el que se ejecuta. Lo siguiente es un extracto de la sección INVOCACIÓN de man bash(énfasis mío):

Cuando se invoca bash como un shell de inicio de sesión interactivo o como un shell no interactivo con la opción --login, primero lee y ejecuta comandos del archivo / etc / profile , si ese archivo existe. Después de leer ese archivo, busca ~ / .bash_profile, ~ / .bash_login y ~ / .profile, en ese orden , y lee y ejecuta comandos del primero que existe y es legible. La opción --noprofile se puede usar cuando se inicia el shell para inhibir este comportamiento.

Cuando se inicia un shell interactivo que no es un shell de inicio de sesión , bash lee y ejecuta comandos desde /etc/bash.bashrc y ~ / .bashrc , si existen estos archivos. Esto puede inhibirse utilizando la opción --norc. La opción de archivo --rcfile obligará a bash a leer y ejecutar comandos desde el archivo en lugar de /etc/bash.bashrc y ~ / .bashrc.

Lo que todo esto significa es que está editando el archivo incorrecto. Puede probar esto cayendo a una consola virtual usando Ctrl+ Alt+ F2(regrese a la GUI con Alt+ F7, o F8dependiendo de su configuración) e inicie sesión allí. Verá que su solicitud y sus alias están disponibles.

Por lo tanto, para que la configuración que desee se aplique a los shells que no son de inicio de sesión, el tipo que obtiene cada vez que abre un terminal, debe realizar los cambios en su ~/.bashrclugar. Alternativamente, también puede colocar sus alias en el archivo ~/.bash_aliases(sin embargo, tenga en cuenta que esta es una característica de Ubuntu y no debe esperar que funcione en otras distribuciones).

Para obtener más detalles sobre qué archivo debe usarse para qué, consulte aquí .


NOTAS

  • Debian (y por extensión Ubuntu) también tiene la ~/.profilefuente predeterminada ~/.bashrc. Esto significa que cualquier cambio que realice ~/.bashrctambién será heredado por los shells de inicio de sesión, pero i) este no es el caso en todas las máquinas Linux / Unix y ii) lo inverso no es cierto, por lo que generalmente siempre debe trabajar con ~/.bashrc& co en lugar de ~/.profileo /etc/profile.

  • Además, una nota general sobre el uso, los cambios realizados en los archivos de configuración /etcafectarán a todos los usuarios. Por lo general, esto no es lo que desea hacer y debe evitarse. Siempre debe usar los archivos equivalentes en su directorio de inicio ( ~/).

  • Los diversos archivos de configuración se leen secuencialmente. Específicamente, para los shells de inicio de sesión, el orden es:

    /etc/profile -> /etc/profile.d/* (in alphabetical order) -> ~/.profile

    Esto significa que cualquier configuración sobre ~/.profilesobrescribirá todo lo establecido en los archivos anteriores.

terdon
fuente
1
De acuerdo con esta publicación howtolamp.com/articles/… , también puede ejecutar echo $0desde un terminal y si la salida tiene el prefijo "-", entonces está en un shell de inicio de sesión.
stackoverflower
@stackoverflower no está en mi sistema. Eso funciona para un shell de inicio de sesión remoto e interactivo. No parece cuando se ejecuta bash -l. En cualquier caso, ¿por qué es eso relevante? La pregunta no es sobre cómo verificar qué tipo de shell está ejecutando.
terdon
publicación magnífica, me pregunto por qué no apareció en Google cuando tuve el mismo problema
Donato
@stackoverflower Si se "$0"expande a algo que comienza con -, entonces sabes que tienes un shell de inicio de sesión. Pero lo contrario no es cierto: la ausencia de -no garantiza que no esté en un shell de inicio de sesión. Las formas más comunes de iniciar shells de inicio de sesión le dan una ventaja -, pero no todas. man bashnos dice "Un shell de inicio de sesión es aquel cuyo primer carácter del argumento cero es a -, o uno que comenzó con la --loginopción". ( -les la forma abreviada de --login; son equivalentes ). En Bash puede ejecutar shopt login_shellpara verificar.
Eliah Kagan
2

Otra posibilidad, especialmente para los ajustes como los ajustes de historia HISTSIZE, HISTFILESIZE, HISTCONTROL, y PS1es que los archivos se cargan, pero los ajustes se sobrescriben en otro archivo que es fuente posterior, siendo la causa más probable ~/.bashrc. (Tengo un conjunto predeterminado de configuraciones para nuestros servidores, como un mensaje en rojo para root para advertir al usuario y grandes historiales con marcas de tiempo)

El valor por defecto de Ubuntu .bashrcde /etc/skelconjuntos de varias configuraciones, que podría haber tenido sentido para fijar de algún lugar donde no anular los ajustes establecidos por el propietario del sistema de /etc/profile.d(Al igual que /etc/bash.bashrc) (Si un usuario edita su .bashrc, está bien para sobrescribir la configuración, los archivos predeterminados del sistema son más molestos)

Gert van den Berg
fuente
2

en Debian para la sesión de Terminal resolví este problema para todos los usuarios, así que:

añadido a

sudo nano /etc/bash.bashrc

bloquear

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

de

/etc/profile
Nikolay Baranenko
fuente
1

Sigue este camino:

  • Abra Editar -> Preferencias
  • En la primera pestaña "General", bajo la etiqueta "Comando", active "Ejecutar comando como shell de inicio de sesión"
Mac
fuente
-1

VERSIÓN = "16.04.3 LTS (Xenial Xerus)"

De acuerdo, todos han asumido que la persona aquí no quiere /etc/profile.d/somefile.sh para todos los usuarios, pero en mi caso eso es exactamente lo que quería.

Entonces, en realidad, como resulta con Ubuntu si usa esto y desea que surta efecto en su shell gráfico, todo lo que tiene que hacer es configurar el archivo y luego cerrar sesión y volver a iniciarla. Todas sus consolas o cualquier cosa que inicie, ya sea tipo xterm o tipo de consola (o dejarlo en el shell) ahora tendrán ese archivo de origen.

No es necesario usar .bashrc, etc. para todos los usuarios. Lo siento, esto no estaba claro en la respuesta anterior. Todo lo que dijeron es cierto, pero en realidad no es cierto, ya que todo lo que inicia el administrador de Windows heredará esta configuración, así que solo vuelva a iniciar sesión y resuelva su problema y no se moleste con .bashrc, etc. si su intención es aplicarlo a todos los usuarios .

Isaac Kane Egglestone
fuente
2
Mi problema es exactamente que esto no sucede en el terminal ejecutado bajo la interfaz gráfica de usuario; ni en Ubuntu 16.04.3 o 18.04.
Thomas Arildsen el