En mi .profile
, utilizo el siguiente código para asegurar que las funciones y los alias relacionados con Bash solo se obtienen si el shell de inicio de sesión es realmente Bash :
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
Actualmente estoy en el proceso de poner mis archivos de configuración de shell, scripts y funciones bajo control de versiones. También he recientemente iniciado el proceso de eliminación del bash casuales de scripts de shell que no se benefician de características Bash-específicas, por ejemplo, la sustitución function funcname()
con funcname()
.
Para los archivos de mi concha repositorio, he configurado un pre-confirmación de gancho que se ejecuta la checkbashisms
utilidad de Debian paquete devscripts en cada sh
fichero en el repositorio para asegurarse de que no introduzcan inadvertidamente sintaxis específica de Bash. Sin embargo, esto genera un error para mi .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
Me preguntaba si había una manera de verificar qué shell se está ejecutando que no activaría una advertencia checkbashisms
.
Verifiqué la lista de variables relacionadas con shell enumeradas por POSIX con la esperanza de que una de ellas pudiera usarse para mostrar el shell actual. También he examinado las variables establecidas en un shell de Dash interactivo pero, nuevamente, no he podido encontrar un candidato adecuado.
Por el momento, he excluido .profile
de ser procesado por checkbashisms
; es un archivo pequeño, por lo que no es difícil verificarlo manualmente. Sin embargo, después de investigar el problema, todavía me gustaría saber si hay un método compatible con POSIX para determinar qué shell se está ejecutando (o al menos una forma que no haga checkbashisms
que falle).
Más antecedentes / aclaraciones
Una de las razones por las que pongo mis archivos de configuración de shell bajo control de versiones es para configurar mi entorno en todos los sistemas en los que actualmente me conecto regularmente: Cygwin, Ubuntu y CentOS (ambos 5 y 7, usando Active Directory para el usuario autenticación). Con frecuencia inicio sesión a través de X Windows / entornos de escritorio y SSH para hosts remotos. Sin embargo, me gustaría que esto sea una prueba de futuro y que tenga la menor confianza posible en las dependencias del sistema y otras herramientas.
Lo he estado utilizando checkbashisms
como una comprobación de sanidad simple y automatizada para la sintaxis de mis archivos relacionados con shell. No es una herramienta perfecta, por ejemplo, ya le he aplicado un parche para que no se queje del uso de command -v
mis scripts. Mientras investigaba, aprendí que el propósito real del programa es garantizar el cumplimiento de la política de Debian que, según tengo entendido, se basa en POSIX 2004 en lugar de 2008 (o su revisión de 2013).
fuente
.bash_profile
fuente de ambos.profile
y (condicionalmente).bashrc
.Respuestas:
Tu
el código es completamente compatible con POSIX y la mejor manera de verificar que se esté ejecutando actualmente
bash
. Por supuesto, la$BASH_VERSION
variable es específica de bash, ¡pero esa es específicamente la razón por la que la está usando! ¡Para comprobar que estás corriendobash
!Tenga en cuenta que
$BASH_VERSION
se establecerá sibash
se invoca comobash
osh
. Una vez que haya afirmado que está ejecutandobash
, puede usar[ -o posix ]
como indicador de que se invocó el shell comosh
(aunque esa opción también se establece cuando POSIXLY_CORRECT está en el entorno obash
se llama con-o posix
, o con SHELLOPTS = posix en el entorno. Pero en todos esos casos,bash
se comportará como si se llamara comosh
).Otra variable que podría usar en lugar de
$BASH_VERSION
y quecheckbashism
no parece quejarse a menos que se pase la-x
opción$BASH
. Eso también es específico, porbash
lo que también debería poder usarlo para determinar si está ejecutandobash
o no.También diría que no es realmente un uso adecuado de
checkbashisms
.checkbashisms
es una herramienta para ayudarlo a escribirsh
scripts portátiles (según lash
especificación en la política de Debian, un superconjunto de POSIX), ayuda a identificar la sintaxis no estándar introducida por personas que escriben scripts en sistemas dondesh
hay un enlace simbólicobash
.A
.profile
es interpretado por diferentes shells, muchos de los cuales no son compatibles con POSIX. En general, no se utilizash
como shell de inicio de sesión, pero conchas gustazsh
,fish
obash
con características interactivas más avanzadas.bash
yzsh
, cuando no se llama comosh
y cuando su archivo de sesión de perfil respectivo (.bash_profile
,.zprofile
) no es compatible con POSIX (especialmentezsh
) pero aún se lee.profile
.Entonces, no es la sintaxis POSIX lo que desea,
.profile
sino una sintaxis compatible con POSIX (forsh
),bash
yzsh
si alguna vez va a usar esos shells (posiblemente incluso Bourne, ya que el shell Bourne también se lee.profile
pero no se encuentra comúnmente en sistemas basados en Linux )checkbashisms
Definitivamente lo ayudaría a encontrar bashismos, pero puede no señalar la sintaxis POSIX que no es compatible conzsh
obash
.Aquí, si desea usar un
bash
código específico (como labash
solución de ese error por el cual no se lee~/.bashrc
en shells de inicio de sesión interactivos), un mejor enfoque sería~/.bash_profile
hacerlo (antes o después de buscar~/.profile
dónde pone su sesión común inicializaciones).fuente
checkbashisms
debido a la variable utilizada.$0
para este caso particular?sh
y algún otro shell llamado assh
.dash
se llamó incorrectamente a otro shell que no es bashargv[0] == "bash"
, lo que es totalmente legal, si es poco probable.Usualmente se usa
$0
para este propósito. En el sitio que ha vinculado se encuentra:fuente
$0
el nombre de un script de shell que me olvidé de que también puede referirse al shell actual. ¡Gracias!exec
familia porque permiten que el programa que llama identifique el binario que se ejecuta por separado de la cadena para pasarlo como argumento 0.Por lo general, la variable de entorno SHELL le indica el shell predeterminado. No debería necesitar obtener manualmente el archivo .bashrc (no es cierto, consulte la actualización a continuación), bash debería hacer esto automáticamente, solo asegúrese de que esté en el directorio $ HOME.
La otra opción es hacer algo como:
eso le dirá el comando (sin argumentos, el = sin un valor no mostrará los encabezados de columna) del proceso actual. Salida de ejemplo:
ACTUALIZAR:
Estoy corregido! :)
El .bashrc no siempre se obtiene como se mencionó en los comentarios a continuación y /programming/415403/whats-the-difference-between-bashrc-bash-profile-and-environment
Para que pueda mover su .bashrc a .bash_profile y ver si eso funciona sin tener que hacer la prueba. Si no, tienes la prueba anterior.
fuente
.bashrc
en realidad no proviene de un shell de inicio de sesión pero.profile
(si existe) o lo.bash_profile
son.SHELL
POSIX no lo especifica y, lamentablemente, tampoco lo es lacmd
opción de formatops
.ps -o cmd= $$
debería funcionar prácticamente en todas partes, la$SHELL
variable es completamente irrelevante. Ese es el shell predeterminado del usuario y no tiene relación con qué shell se está ejecutando actualmente o qué shell está ejecutando un script de shell.~/.profile
cuando se inicien como shells de inicio de sesión. Entonces, por ejemplo,$SHELL
podrías sercsh
y corresbash -l
. Eso comenzará bash como un shell de inicio de sesión, por lo que se leerá~/.profile
, pero$SHELL
aún apuntarácsh
. Además,.profile
podría provenir explícitamente de otro script. Dado que el OP busca la máxima robustez, se deben considerar todo tipo de casos. En cualquier caso,$SHELL
no proporciona ninguna información útil sobre el shell actualmente en ejecución.SHELL
no haber sido especificado por POSIX: pubs.opengroup.org/onlinepubs/9699919799/basedefs/…La pregunta solicita el shell de inicio de sesión del usuario , así como el shell actual de una manera que sea agradable
checkbashisms
. Si ese es el shell en el que el usuario inició sesión, usaría el de/etc/passwd
, por ejemplo,Por supuesto, los usuarios pueden iniciar un nuevo shell después de iniciar sesión. Por supuesto, si uno es bash y el otro no, las pruebas de las variables de entorno de bash pueden no ayudar.
Algunos pueden querer usar en
getent
lugar de solo elpasswd
archivo (pero eso no estaría en el alcance de la pregunta).Según el comentario sobre LDAP y la sugerencia de
logname
, este formulario alternativo podría usarse:Mientras lo probaba, noté que
logname
no le gusta su entrada redirigida (así que dejé la expresión dividida). Un programa de verificación rápidagetent
debería funcionar en las plataformas mencionadas (aunque eso debería haberse proporcionado en la pregunta original):fuente
$(logname)
).id
o una variable modificable por el usuario es una opción diferente.$(logname)
no$LOGNAME
. La identificación de usuario y el shell de inicio de sesión se derivan del nombre de usuario utilizado al iniciar sesión. No puede volver del ID de usuario al shell de inicio de sesión, excepto en sistemas donde solo hay un nombre de usuario por ID de usuario. O IOW, la clave principal en la base de datos del usuario es el nombre de usuario, no el uid.