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.
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
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
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
.
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
%
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"
}
}'
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