Cómo obtener shell para auto-detectar el uso de zsh o bash

Tengo una pregunta sobre cómo saber que shell está utilizando el usuario. Supongamos que un script que si el usuario está utilizando zsh, a continuación, poner la RUTA a su .zshrc y si el uso de bash debe poner en .bashrc. Y establecer rvmrc en consecuencia.

#!/usr/bin/env bash
export PATH='/usr/local/bin:$PATH'" >> ~/.zshrc
source ~/.zshrc

He intentado lo siguiente pero no funciona : (

if [[ $0 == "bash ]]; then
  export PATH='/usr/local/bin:$PATH'" >> ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  export PATH='/usr/local/bin:$PATH'" >> ~/.zshrc
fi

# ... more commands ...

if [[ $0 == "bash ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm'" >> ~/.bashrc
  source ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm'" >> ~/.zshrc
  source ~/.zshrc
fi
  • algunas citas son incomparables.
  • ¿No tendría más sentido para poner esto en .profile, que es portable a través de las conchas, incluyendo sh?
  • Hola, porque es una cosa específica para bash o zsh creo…
  • Le sugiero que lea esta sección de la avanzada de bash scripting guide.

6 Kommentare

  1. 28

    Una palabra de advertencia: la pregunta que parece que han preguntado, la pregunta que te quería preguntar, y la pregunta que usted debe tener frecuentes son tres cosas diferentes.

    «De shell que está utilizando el usuario» es ambiguo. Su intento se ve como se está tratando de determinar de shell que se ejecuta la secuencia de comandos. Que siempre va a ser lo que pones en el #! línea del script, a menos que usted quiere que sus usuarios editar el script, así que esto no es útil para usted.

    Lo que quería preguntar, creo, es lo que el favorito del usuario shell es. Esto no puede ser determinado totalmente fiable, pero puede cubrir la mayoría de los casos. Compruebe la SHELL variable de entorno. Si contiene fish, zsh, bash, ksh o tcsh, el favorito del usuario shell es, probablemente, que la shell. Sin embargo, esta no es la pregunta adecuada para su problema.

    Archivos como .bashrc, .zshrc, .cshrc y así sucesivamente, son archivos de inicialización de shell. Ellos no son el lugar adecuado para definir las variables de entorno. Una variable de entorno definidas no sólo estarían disponibles en un terminal donde el usuario que lanzó shell y no en los programas iniciados a partir de una interfaz gráfica de usuario. La definición también invalidar cualquier personalización que el usuario puede haber hecho en un subsession.

    El lugar correcto para definir una variable de entorno en un archivo de inicio de sesión. Esto es principalmente relacionado a la elección del usuario de shell. Lamentablemente, no hay un solo lugar para definir las variables de entorno. En una gran cantidad de sistemas, ~/.profile va a trabajar, pero esto no es universal. Ver https://unix.stackexchange.com/questions/4621/correctly-setting-environment y la de otros puestos, yo el enlace que hay para una discusión más larga.

    • «Que siempre va a ser lo que pones en el #! la línea de la secuencia de comandos» – Eso no es cierto, ya que un usuario podría fácilmente pasar el script de nombre de archivo como parámetro para cualquier shell.
    • Y el usuario probablemente será pasar el script de nombre de archivo como parámetro a una muestra aleatoria de shell, si el script no está marcado como ejecutable. Dependiendo de su proceso de instalación, esto puede o puede no ser el caso.
    • Como era de esperar, la solución aceptada sólo ofrece retórica de la amonestación y el castigo, en lugar de soluciones significativas. Todo el mundo quiere adldel respuesta acreditada en su lugar, lo que ofrece varias de propósito general fragmentos de abordar la pregunta.
    • Creo que mi respuesta fue aceptada porque responde a lo que el autor de la pregunta quería preguntar. adl respuesta es un tratamiento más detallado de este título, sino que a menudo es mal la pregunta.
  2. 113

    Si la cáscara es Zsh, la variable $ZSH_VERSION está definido. Igualmente para el Bash y $BASH_VERSION.

    if [ -n "$ZSH_VERSION" ]; then
       # assume Zsh
    elif [ -n "$BASH_VERSION" ]; then
       # assume Bash
    else
       # asume something else
    fi

    Sin embargo, estas variables sólo te digo que la shell se utiliza para ejecutar el código anterior. Por lo que tendría que source este fragmento en el shell del usuario.

    Como alternativa, puede utilizar la $SHELL variable de entorno (que debe contener la ruta de acceso absoluta a la preferida del usuario shell) y supongo que el shell de el valor de la variable:

    case $SHELL in
    */zsh) 
       # assume Zsh
       ;;
    */bash)
       # assume Bash
       ;;
    *)
       # assume something else
    esac

    Por supuesto, el de arriba se producirá cuando /bin/sh es un enlace simbólico a /bin/bash.

    Si quieres confiar en $SHELL, lo más seguro es que en realidad ejecutar algún código:

    if [ -n "`$SHELL -c 'echo $ZSH_VERSION'`" ]; then
       # assume Zsh
    elif [ -n "`$SHELL -c 'echo $BASH_VERSION'`" ]; then
       # assume Bash
    else
       # asume something else
    fi

    Esta última sugerencia se puede ejecutar desde una secuencia de comandos, independientemente de que la shell se utiliza para ejecutar la secuencia de comandos.

    • Hola Gracias por tu respuesta. He probado la última método. Mientras me reside en zsh, me encontré con su guión, pero aún así dice que estoy usando bash. Me tomé una foto: imagen
    • Ejecutar el script en bash, por lo que se informó correctamente se estaba ejecutando en bash.
    • Se ejecutó zsh en un terminal. A partir de esa interactivo zsh, ejecutó bash para interpretar una secuencia de comandos. En esa secuencia, la prueba de shell que se ejecuta la secuencia de comandos, y la respuesta fue bash.
    • el último código de pedazo que falta un «$» delante de la CONCHA. Traté de editarlo, pero StackOverflow ediciones requieren al menos 6 caracteres para ser cambiado.
  3. 43

    Acaba de hacer echo $0
    dice -zsh si es zsh y -bash si es bash

    EDIT: a Veces se vuelve -zsh y a veces zsh y lo mismo con bash, nose por qué.

    • Esto no funciona para todos los proyectiles, pero todavía es mi go-para método alguna vez que me siento en un CLI; funciona más veces de las que no. Conchas, tales como el Pescado no va a devolver nada para echo $0
    • El -zsh o -bash se utiliza para indicar un shell de inicio de sesión. Si no tiene el - delante del nombre, el usuario está usando una shell de inicio de sesión
    • Esto no funciona si estás en una función, donde $0 devolverá el nombre de la función.
  4. 3

    Una alternativa, podría no funcionar para todos los shells.

    for x in $(ps -p $$)
    do
      ans=$x
    done
    echo $ans
    • ps -p $$ --no-headers -o cmd es un poco mejor.
    • Excepto cuando no funciona: ps: unknown option -- no-headers
  5. 1

    Aquí es cómo estoy haciendo se basa en una respuesta anterior de Gilles :

    if [ -n "$ZSH_VERSION" ]; then
      SHELL_PROFILE="$HOME/.zprofile"
    else
      SHELL_PROFILE="$HOME/.bash_profile"
    fi
    echo "export VAR1=whatever" >> $SHELL_PROFILE
    echo "INFO: Refreshing your shell profile: $SHELL_PROFILE"
    if [ -n "$ZSH_VERSION" ]; then
      exec zsh --login
    else
      source $SHELL_PROFILE
    fi
  6. 0

    A mí mismo tener un problema similar, se establecieron por:

    _shell="$(ps -p $$ --no-headers -o comm=)"                                                                                                       
    if [[ $_shell == "zsh" ]]; then                                                                                                                  
        read -q -s "?Do it?: "                                                                                                                    
    fi                                                                                                                                               
    elif [[ $_shell == "bash" || $_shell == "sh" ]]; then                                                                                              
        read -n 1 -s -p "Do it [y/n] "                                                                                                            
    fi                                                                                                                                               

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea