scripting bash: si los argumentos son iguales a esta cadena, defina una variable como esta cadena


225

Estoy haciendo un script bash y ahora recibí una llamada variable sourcey una matriz llamada samples, así:

source='country'
samples=(US Canada Mexico...)

Como quiero expandir el número de fuentes (y cada fuente tiene sus propias muestras) intenté agregar algunos argumentos para hacer esto. Intenté esto:

source=""
samples=("")
if [ $1="country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
   echo "try again"
fi

pero cuando ejecuté mi script source countries.sh countryno funcionó. ¿Qué estoy haciendo mal?


2
como no funciona Cuando lo ejecutas, aparece un error, o dice "inténtalo de nuevo", ¿o algo más?
mal otto

2
Sí, puede pensar "la pregunta es muy sencilla". pero has estado pensando en esto por un tiempo. Considere editar su pregunta para incluir los resultados requeridos y cualquier mensaje de error que reciba. +1 para probar algo y un buen formato de pregunta. buena suerte.
shellter

¿Por qué este código es el mismo que la solución propuesta y aceptada? Eso es confuso ... Supongo que la pregunta inicial no tenía los espacios justo después del corchete de apertura y antes del corchete de cierre de la oración if.
Stef

66
@Stef si te fijas bien, $1="country"vs.$1 = "country"
Será el

Respuestas:


413

No te olvides de los espacios:

source=""
samples=("")
if [ $1 = "country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
  echo "try again"
fi

121
¡¡¡No puedo creer que haya pasado tres horas en esto, y solo era un problema de espacios !!!! ... GRACIAS @Alex
Alejandro

1
¿Por qué usas samples="US Canada Mexico..."después de introducir la creación de matriz antes samples=(US Canada Mexico...)?
usuario desconocido

10
Me encontré con problemas con esto cuando la variable de la izquierda era una cadena vacía. Fix fue if [ "$1" = "country" ]; then.
andrewb

8
Ok eso es todo. Bash oficialmente obtiene mi voto para ser el lenguaje de comandos más anticuado pero aún utilizado. La sintaxis es tan poco intuitiva que duele. Realmente no hay lugar para ello en 2016+. Autores de @Systemd: ¿pueden hacer que "construir un shell de Linux que no apesta" sea su próximo proyecto? Te arrojaré dinero.
masi

3
@masi a veces creo que la intención original de Unix era "seguridad laboral a través de la oscuridad". Si las herramientas fueran crípticas de usar, difíciles de entender y, en general, fuera del alcance de los grandes sin lavar sin el conocimiento interno transmitido del maestro al padwan, se aseguraría de que siempre hubiera trabajo para los "entendidos". Esta filosofía es evidente en toda la construcción "RFC" y en el lenguaje florido utilizado en los documentos de hombre, que aunque técnicamente le dice cómo usar las herramientas, realmente estaban allí para cumplir con el requisito de haber documentado las herramientas. Poco ha cambiado.
no sincronizado

184

Puede usar operadores "=" o "==" para la comparación de cadenas en bash. El factor importante es el espacio entre los corchetes. El método apropiado es que los corchetes contengan espacios dentro y los operadores contengan espacios alrededor. En algunos casos, funcionan diferentes combinaciones; sin embargo, lo siguiente pretende ser un ejemplo universal.

if [ "$1" == "something" ]; then     ## GOOD

if [ "$1" = "something" ]; then      ## GOOD

if [ "$1"="something" ]; then        ## BAD (operator spacing)

if ["$1" == "something"]; then       ## BAD (bracket spacing)

Además, tenga en cuenta que los corchetes dobles se manejan de manera ligeramente diferente en comparación con los corchetes individuales ...

if [[ $a == z* ]]; then   # True if $a starts with a "z" (pattern matching).
if [[ $a == "z*" ]]; then # True if $a is equal to z* (literal matching).

if [ $a == z* ]; then     # File globbing and word splitting take place.
if [ "$a" == "z*" ]; then # True if $a is equal to z* (literal matching).

¡Espero que eso ayude!


12

Parece que está buscando analizar argumentos de línea de comandos en su script bash. He buscado esto recientemente yo mismo. Encontré lo siguiente que creo que lo ayudará a analizar los argumentos:

http://rsalveti.wordpress.com/2007/04/03/bash-parsing-arguments-with-getopts/

Agregué el fragmento a continuación como tl; dr

#using : after a switch variable means it requires some input (ie, t: requires something after t to validate while h requires nothing.
while getopts ht:r:p:v OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         t)
             TEST=$OPTARG
             ;;
         r)
             SERVER=$OPTARG
             ;;
         p)
             PASSWD=$OPTARG
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $TEST ]] || [[ -z $SERVER ]] || [[ -z $PASSWD ]]
then
     usage
     exit 1
fi

./script.sh -t prueba -r servidor -p contraseña -v

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.