2009-07-07 9 views
22

Estoy tratando de comparar dos cadenas en un simple script de shell. que estaba usando /bin/sh en lugar de /bin/bash, y después de muchas horas de depuración, resulta que sh (que es en realidad un guión) no puede manejar este bloque de código:comparación de bash, dash y cadena

if [ "$var" == "string" ] 
then 
    do something 
fi 

¿Cuál es una manera portátil para comparar cadenas usando /bin/sh? Sé que siempre puedo hacer lo contrario usando! =, Pero me pregunto sobre una forma más limpia y portátil.

+2

Puede usar '[[$ var ==" cadena "]]', que es POSIX, pero opcional (afaik). O puede usar '[" $ var "=" string "]'. Tenga en cuenta el '" "' alrededor de la variable en la edición de un solo paréntesis: se requiere en caso de que '$ var' esté vacía –

+0

La parte importante son las comillas de' $ var' mencionadas. Sin las comillas, '[$ var =" value "]' se convierte en '[=" value "]' lo que confunde al caparazón de forma horrenda. Probablemente verá un error como _ "[: =: operador unario esperado" _ cuando encuentre una variable vacía de lo contrario. –

+0

Entiendo acerca de "$ var" frente a $ var, mi problema fue == vs. = – LiraNuna

Respuesta

32

dash es un shell POSIX muy estricto, si funciona en dash es casi seguro que funcionaría en otro shell POSIX.

Probar:

if [ "$var" = "string" ] 
then 
    some_command 
fi 
8

¿Por qué existe la posibilidad de que su script sea ejecutado por el shell "incorrecto"? Me gustaría pensar que podría hacer que un pre-requisito de su producto mediante el uso de la línea SH-bang estándar en la parte superior de su script:

#!/bin/bash 

Incluso si un usuario utiliza un shell diferente, las otras conchas Por lo general, siguen allí y, si no, simplemente se quejan y afirman que son un requisito previo.

Exactamente de la misma manera que un nivel de kernel específico, o la existencia de awk, puede ser un pre-requisito.

Para su pregunta específica, creo que tanto sh y bash permiten el single '=' para ser utilizado para la comparación de cadenas - que es un comportamiento POSIX:

if [ "a" = "a" ] ; then 
    echo yes 
fi 

yes 
+1

* "¿Por qué existe la posibilidad de que su script sea ejecutado por el shell" erróneo "?" * - ¿Es posible controlar qué shell usa Autoconf? (Esa es la razón por la que estoy buscando la respuesta) – jww

3

Uso = en lugar de ==. Las comparaciones son manejadas por la prueba (1). /usr/bin/[ es típicamente un enlace a /usr/bin/test. La única diferencia es que si usa [ en un script de shell, también se requiere ].

Tenga en cuenta que bash tiene incorporado test/[, por lo que en realidad no usa /usr/bin/test.

-3

Usted puede usar awk

awk 'BEGIN{ 
string1="test" 
string2="tes1t" 
if(s1==s2){ 
    print "same string" 
}else{ 
    print "not same" 
} 
}' 
1

Las respuestas ya anunciados son ciertamente correcto, pero puede valer la pena señalar que la expansión de vez en cuando parámetro puede servir al mismo propósito con tal algo de flexibilidad adicional.

% p() { printf 'notvar = %b\n' "${notvar##"${string1}"}${string2}" ; } 
% string1='some stuff about things\c' 
% string2='some different stuff maybe' 
% notvar="$string1" p 
> 'some different stuff maybe' 
% notvar="$string2" p 
> 'some stuff about things' 

Ok, así que lo anterior no es súper útil como es, sino también en cuenta que puede utilizar los métodos similares para las variables de prueba en los documentos internos, en línea asignaciones de variables si es necesario (en un grado ...), o incluso como un medio más corto (¡y más rápido!) de escribir tu primera declaración.

[ ! "${var##"string"}" ] && _MATCH || _NOMATCH 

O incluso ...

[ ${#var#*"${s=string}"} -lt ${#var} ] && _SUB_STRING_TEST=TRUE 

posible que incluso ...

% p() { printf '%s is %s of %s' "$2" "${var_chk-not}" "$1" 
> }<<HEREDOC 
> ${in="${1##*"${2}"*}"} 
> ${in:- 
>  ${in="${1##"${2}"}"} 
>  ${in:-${var_chk=all} 
>  ${var_chk=some} 
> } 
> HEREDOC 
% 
+1

No estoy seguro de ver el gran beneficio de estas técnicas a menos que intente ganar un concurso de ofuscación. – swdev