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.


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


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.


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 

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'


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


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

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.