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 checkbashismsutilidad de Debian paquete devscripts en cada shfichero 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 .profilede 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 checkbashismsque 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 checkbashismscomo 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 -vmis 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_profilefuente de ambos.profiley (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_VERSIONvariable 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_VERSIONse establecerá sibashse invoca comobashosh. 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 obashse llama con-o posix, o con SHELLOPTS = posix en el entorno. Pero en todos esos casos,bashse comportará como si se llamara comosh).Otra variable que podría usar en lugar de
$BASH_VERSIONy quecheckbashismno parece quejarse a menos que se pase la-xopción$BASH. Eso también es específico, porbashlo que también debería poder usarlo para determinar si está ejecutandobasho no.También diría que no es realmente un uso adecuado de
checkbashisms.checkbashismses una herramienta para ayudarlo a escribirshscripts portátiles (según lashespecificació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 dondeshhay un enlace simbólicobash.A
.profilees interpretado por diferentes shells, muchos de los cuales no son compatibles con POSIX. En general, no se utilizashcomo shell de inicio de sesión, pero conchas gustazsh,fishobashcon características interactivas más avanzadas.bashyzsh, cuando no se llama comoshy 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,
.profilesino una sintaxis compatible con POSIX (forsh),bashyzshsi alguna vez va a usar esos shells (posiblemente incluso Bourne, ya que el shell Bourne también se lee.profilepero no se encuentra comúnmente en sistemas basados en Linux )checkbashismsDefinitivamente lo ayudaría a encontrar bashismos, pero puede no señalar la sintaxis POSIX que no es compatible conzshobash.Aquí, si desea usar un
bashcódigo específico (como labashsolución de ese error por el cual no se lee~/.bashrcen shells de inicio de sesión interactivos), un mejor enfoque sería~/.bash_profilehacerlo (antes o después de buscar~/.profiledónde pone su sesión común inicializaciones).fuente
checkbashismsdebido a la variable utilizada.$0para este caso particular?shy algún otro shell llamado assh.dashse llamó incorrectamente a otro shell que no es bashargv[0] == "bash", lo que es totalmente legal, si es poco probable.Usualmente se usa
$0para este propósito. En el sitio que ha vinculado se encuentra:fuente
$0el nombre de un script de shell que me olvidé de que también puede referirse al shell actual. ¡Gracias!execfamilia 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
.bashrcen realidad no proviene de un shell de inicio de sesión pero.profile(si existe) o lo.bash_profileson.SHELLPOSIX no lo especifica y, lamentablemente, tampoco lo es lacmdopción de formatops.ps -o cmd= $$debería funcionar prácticamente en todas partes, la$SHELLvariable 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.~/.profilecuando se inicien como shells de inicio de sesión. Entonces, por ejemplo,$SHELLpodrías sercshy corresbash -l. Eso comenzará bash como un shell de inicio de sesión, por lo que se leerá~/.profile, pero$SHELLaún apuntarácsh. Además,.profilepodrí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,$SHELLno proporciona ninguna información útil sobre el shell actualmente en ejecución.SHELLno 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
getentlugar de solo elpasswdarchivo (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
lognameno le gusta su entrada redirigida (así que dejé la expresión dividida). Un programa de verificación rápidagetentdebería funcionar en las plataformas mencionadas (aunque eso debería haberse proporcionado en la pregunta original):fuente
$(logname)).ido 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.