Error de comando no encontrado en la asignación de variables Bash

521

Tengo este script llamado test.sh:

#!/bin/bash
STR = "Hello World"
echo $STR

cuando corro sh test.shme sale esto:

test.sh: line 2: STR: command not found

¿Qué estoy haciendo mal? Miro los tutoriales de scripts de bash extremadamente básicos / principiantes en línea y así es como dicen declarar variables ... Así que no estoy seguro de qué estoy haciendo mal.

Estoy en Ubuntu Server 9.10. Y sí, bash se encuentra en /bin/bash.

Jake Wilson
fuente
49
Me alegro de que hayas hecho la pregunta, ¡no eres el único bash noob por ahí!
Miller el gorila
66
Gracias por hacer esa pregunta. Esta no es una pregunta por la que avergonzarse. Estoy trabajando hasta tarde en la oficina y no hay un experto en Bash a mi alrededor para responder esto.
Adway Lele
3
En estos días (¡casi siete años después!) Hay un analizador / analizador FOSS llamado shellcheck que detectará automáticamente este y otros problemas de sintaxis comunes. Puede usarse en línea o instalarse sin conexión e integrarse en su editor.
ese otro tipo
Consulte también stackoverflow.com/questions/26971987/…
tripleee el
Te recomiendo que uses: en #!/usr/bin/env bashlugar de poner directamente, a #!/bin/bashmenos que estés absolutamente seguro de que estás bashdentro /bindebido a esta respuesta: stackoverflow.com/a/21613044/3589567
Alejandro Blasco

Respuestas:

929

No puede tener espacios alrededor de su signo '='.

Cuando escribes:

STR = "foo"

bash intenta ejecutar un comando llamado STR con 2 argumentos (las cadenas '=' y 'foo')

Cuando escribes:

STR =foo

bash intenta ejecutar un comando llamado STR con 1 argumento (la cadena '= foo')

Cuando escribes:

STR= foo

bash intenta ejecutar el comando foo con STR establecido en la cadena vacía en su entorno.

No estoy seguro de si esto ayuda a aclarar o si es una simple ofuscación, pero tenga en cuenta que:

  1. el primer comando es exactamente equivalente a: STR "=" "foo",
  2. el segundo es el mismo que STR "=foo",
  3. y el último es equivalente a STR="" foo.

La sección relevante de la especificación del lenguaje sh, sección 2.9.1 establece:

Un "comando simple" es una secuencia de asignaciones y redirecciones de variables opcionales, en cualquier secuencia, opcionalmente seguida de palabras y redirecciones, terminadas por un operador de control.

En ese contexto, a wordes el comando que bash va a ejecutar. Cualquier cadena que contenga =(en cualquier posición que no sea al principio de la cadena) que no sea una redirección es una asignación variable, mientras que cualquier cadena que no sea una redirección y no contenga =es un comando. En STR = "foo", STRno es una asignación variable.

William Pursell
fuente
2
Si tiene una variable con un nombre que contiene "-", se produce el mismo error. En ese caso, la solución es eliminar el "-"
chomp
1
chomp @ En la regla 7b de la sección 2.10.10 de pubs.opengroup.org/onlinepubs/9699919799 "Si todos los caracteres que preceden '=' forman un nombre válido (ver Nombre XBD), se devolverá el token ASSIGNMENT_WORD". Siguiendo el enlace a la sección 3.231 de pubs.opengroup.org/onlinepubs/9699919799 , encontramos "En el lenguaje de comandos de shell, una palabra que consiste únicamente en guiones bajos, dígitos y alfabéticos del juego de caracteres portátil. El primer carácter de un nombre es no un dígito ". Entonces la palabra FOO-BAR=quxno es una asignación variable ya FOO-BARque no es un nombre válido.
William Pursell
2
Estoy ofreciendo una recompensa para recompensar esta explicación clara a un problema siempre común para principiantes (bueno, y también para poder encontrarlo más rápido cada vez que quiera vincularlo: D). ¡Gracias por hacer las cosas tan fáciles!
fedorqui 'SO deja de dañar'
1
@fedorqui Gracias! No estoy del todo convencido de que esta sea una explicación clara, y a menudo me pregunto si podría simplificarse.
William Pursell
159

Suelta los espacios alrededor del =letrero:

#!/bin/bash 
STR="Hello World" 
echo $STR 
Joey
fuente
99
Sin embargo, esto es divertido, ya que también set foo = bares un error común en los archivos por lotes de Windows, y allí se ridiculiza el idioma del lote ;-)
Joey
Gracias @joey Estaba atrapado en escribir un script de shell donde estaba inicializando variables con espacios después de "=". Me salvaste el día
Lalit Rao
¿Por qué bash no acepta números en el campo izquierdo? como 3 = "Hello World", se queja del comando no encontrado
Freedo
6

En el modo interactivo, todo se ve bien:

$ str="Hello World"
$ echo $str
Hello World

Obviamente (!) Como dijo Johannes, no hay espacio alrededor =. En caso de que haya espacio alrededor, =entonces en el modo interactivo da errores como

No se encontró el comando 'str'

Arkapravo
fuente
2
Pero tenga en cuenta que el OP estaba diciendo STR = "Hello World", por lo que esta respuesta no se aplica aquí.
Fedorqui 'SO deja de dañar'
@Arkapravo, ¿cuál es el significado del modo interactivo? ¿Tiene algo que ver con la $marca
Kasun Siyambalapitiya
@KasunSiyambalapitiya por "modo interactivo" se refiere a escribir esos comandos en el terminal real, no en un script.
numbermaniac
5

Sé que esto ha sido respondido con una respuesta de muy alta calidad. Pero, en resumen, no puedes tener espacios.

#!/bin/bash
STR = "Hello World"
echo $STR

No funcionó debido a los espacios alrededor del signo igual. Si tuvieras que correr ...

#!/bin/bash
STR="Hello World"
echo $STR

Funcionaria

Derek Haber
fuente
2

Cuando define cualquier variable, entonces no tiene que poner espacios adicionales.

P.ej

name = "Stack Overflow"  
// it is not valid, you will get an error saying- "Command not found"

Entonces elimine espacios:

name="Stack Overflow" 

y funcionará bien

Ravi Solanki
fuente