2011-08-11 9 views
8

Quiero entender if else declaración en sh scriptingsh/bash si else

Así que escribió el siguiente para averiguar si JAVA_HOME está situado en el entorno o no, que escribió el guión a continuación

#!/bin/sh 
if [ $JAVA_HOME != "" ] 
then 
    echo $JAVA_HOME 
else 
    echo "NO JAVA HOME SET" 
fi 

Esta mi salida a env

sh-3.2$ env 

SHELL=/bin/csh 
TERM=xterm 
HOST=estilor 
SSH_CLIENT=10.15.16.28 4348 22 
SSH_TTY=/dev/pts/18 
USER=asimonraj 
GROUP=ccusers 
HOSTTYPE=x86_64-linux 
PATH=/usr/local/bin:/bin:/home/asimonraj/java/LINUXJAVA/java/bin:/usr/bin 
MAIL=/var/mail/asimonraj 
PWD=/home/asimonraj/nix 
HOME=/home/asimonraj 
SHLVL=10 
OSTYPE=linux 
VENDOR=unknown 
LOGNAME=asimonraj 
MACHTYPE=x86_64 
SSH_CONNECTION=100.65.116.248 4348 100.65.116.127 22 
_=/bin/env 

pero me sale debajo de la salida

sh-3.2$ ./test.sh 
./test.sh: line 3: [: !=: unary operator expected 
NO JAVA HOME SET 

Respuesta

13

Usted está ejecutando en una limitación de la estúpida manera sh expande argumentos. La línea 3 del script se está ampliando para:

if [ != ] 

Qué sh no puede averiguar qué hacer con él. Pruebe este truco desagradable en el tamaño:

if [ x$JAVA_HOME != x ] 

Ambos argumentos tienen que ser no vacío, por lo que sólo tendremos que lanzar una x en ambos y ver qué pasa.

Alternativamente, hay un operador independiente para las pruebas si una cadena es no vacía: (. -z pruebas si la siguiente cadena está vacía)

if [ !-z $JAVA_HOME ] 

+6

'if [" $ JAVA_HOME "! =" "]' También debería funcionar. –

+0

@Keith Thompson: @diskwuff describe la convención estándar aquí. También funciona si '$ JAVA_HOME' se establece en otras cosas' test' se ahogará, aunque noto que 'bash' es bastante indulgente. – reinierpost

+0

@reinierpost: ¿Está diciendo que el prefijo "x" es la convención estándar? Probablemente fue en un momento, pero no creo que sea necesario hoy, y rara vez lo veo. Los operandos no tienen que ser no vacíos, solo tienen que ser "palabras" individuales (donde una palabra puede ser la cadena vacía). (Puede ser que algunos shells muy antiguos no distinguen entre un argumento de '" "' y ningún argumento en absoluto, pero me sorprendería si algún shell en el uso actual común tuviera ese problema). –

1
if [ -z $JAVA_HOME ] 
then 
    echo $JAVA_HOME 
else 
    echo "NO JAVA HOME SET" 
fi 
+0

cheque aquí http://tldp.org/LDP/abs/html/comparison-ops .html – Kracekumar

+0

[Usar cuatro espacios para sangrar bloques de código] (http://stackoverflow.com/editing-help#code), hace que sean más fáciles de leer. (O simplemente resalte el código, y haga clic en el botón '{}'.) – OverZealous

+0

@OverZealous: lo intenté pero no funciona incluso presionando 4 veces la barra espaciadora, no encuentro ningún cambio en la vista previa de salida. – Kracekumar

1

la -n y -z son pruebas deben ser usado aquí:

if [ -n "$JAVAHOME" ]; then 
    echo "$JAVAHOME"; 
else 
    echo "\$JAVAHOME not set"; 
fi 
+0

Sugiero usar comillas simples en lugar de comillas dobles y escapes en caso de que no desee que ocurra la expansión. De lo contrario, se ve bien. –

1

Tenga en cuenta que si desea determinar si se establece una variable, es probable que no desee t para usar if/else o test ([). Es más típico para hacer cosas como:

 
# Abort if JAVA_HOME is not set (or empty) 
: ${JAVA_HOME:?JAVA_HOME is unset} 

o

 
# report the value of JAVA_HOME, or a default value 
echo ${JAVA_HOME:-default value} 

o

 
# Assign JAVA_HOME if it is unset (or empty) 
: ${JAVAHOME:=default value} 
+0

El caso de eco necesita más comillas. De lo contrario, esta es la mejor respuesta que he visto hasta ahora (la falta de calidad es algo desalentadora). –

+0

Si JAVA_HOME contiene elementos de ruta con espacios, ¡hay más problemas con el sistema de los que se pueden resolver con comillas dobles! –

+0

El hecho de que sea una mala práctica elegir un nombre de archivo o ubicación que provoque errores en los programas con errores no es excusa para que esos programas tengan errores. –

Cuestiones relacionadas