comparación de bash, guión y cuerda


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

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

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

Author: Justin M. Keyes, 2009-07-07

5 answers

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

Intenta:

if [ "$var" = "string" ]
then
    some_command
fi
 36
Author: J-16 SDiZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-28 19:56:06

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

#!/bin/bash

Incluso si un usuario usa un shell diferente, los otros shell generalmente siguen ahí y, si no, simplemente se quejan y declaran que son un pre-req.

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

Para su pregunta específica, creo que tanto sh como bash permiten que se use el único '=' para comparaciones de cadenas, es decir, el comportamiento POSIX:

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

yes
 9
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-07 00:32:43

Use = en lugar de ==. Las comparaciones son manejadas por test(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 un test/[, así que en realidad no usa /usr/bin/test.

 3
Author: skoob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 05:40:45

Las respuestas ya publicadas son ciertamente correctas, pero puede valer la pena señalar que ocasionalmente la expansión de parámetros puede servir para el mismo propósito con tal vez alguna 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'

De acuerdo, por lo que lo anterior no es súper útil como es, pero también considere que puede usar los métodos similares para probar variables aquí: documentos, asignaciones de variables en línea si es necesario (hasta cierto punto...), o incluso como un más corto (y más rápido!) medios de escribir su primera instrucción.

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

O incluso...

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

, Posiblemente, 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
Author: mikeserv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-15 07:39:39

Puedes usar awk

awk 'BEGIN{
 string1="test"
 string2="tes1t"
 if(s1==s2){
    print "same string"
 }else{
    print "not same"
 }
}'
 -3
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-07 01:52:41