Erro de comando não encontrado na atribuição de variável Bash

521

Eu tenho esse script chamado test.sh:

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

quando corro sh test.sh, recebo o seguinte:

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

O que estou fazendo errado? Eu olho para os tutoriais de script bash extremamente básicos / para iniciantes on-line e é assim que eles dizem para declarar variáveis ​​... Portanto, não tenho certeza do que estou fazendo de errado.

Estou no Ubuntu Server 9.10. E sim, o bash está localizado em /bin/bash.

Jake Wilson
fonte
49
Estou feliz que você fez a pergunta, você não é o único bash noob por aí!
miller the gorilla
6
Obrigado por fazer essa pergunta. Esta não é uma questão para se envergonhar. Estou trabalhando tarde da noite no escritório e não há nenhum especialista em Bash ao meu redor para responder a isso.
Adway Lele
3
Hoje em dia (quase sete anos depois!), Existe um analisador / analisador de software livre chamado shellcheck que detecta automaticamente esse e outros problemas comuns de sintaxe. Pode ser usado online ou instalado offline e integrado ao seu editor.
aquele outro cara
Veja também stackoverflow.com/questions/26971987/…
tripleee 2/17/17
Eu recomendo que você usar: #!/usr/bin/env bashem vez de colocar diretamente #!/bin/basha menos que você esteja absolutamente certo seus bashé em /bincausa de esta resposta: stackoverflow.com/a/21613044/3589567
Alejandro Blasco

Respostas:

929

Você não pode ter espaços ao redor do seu sinal '='.

Quando você escreve:

STR = "foo"

o bash tenta executar um comando chamado STR com 2 argumentos (as strings '=' e 'foo')

Quando você escreve:

STR =foo

o bash tenta executar um comando chamado STR com 1 argumento (a sequência '= foo')

Quando você escreve:

STR= foo

O bash tenta executar o comando foo com STR definido como a sequência vazia em seu ambiente.

Não tenho certeza se isso ajuda a esclarecer ou se é mera ofuscação, mas observe que:

  1. o primeiro comando é exatamente equivalente a: STR "=" "foo",
  2. o segundo é o mesmo que STR "=foo",
  3. e o último é equivalente a STR="" foo.

A seção relevante da especificação da linguagem sh, seção 2.9.1, declara:

Um "comando simples" é uma sequência de atribuições e redirecionamentos de variáveis ​​opcionais, em qualquer sequência, opcionalmente seguidos por palavras e redirecionamentos, finalizados por um operador de controle.

Nesse contexto, a wordé o comando que o bash será executado. Qualquer sequência que contenha =(em qualquer posição que não seja o início da sequência) que não seja um redirecionamento é uma atribuição de variável, enquanto qualquer sequência que não seja um redirecionamento e não contenha =será um comando. In STR = "foo", STRnão é uma atribuição de variável.

William Pursell
fonte
2
Se você tiver uma variável com um nome que contenha "-", o mesmo erro ocorrerá. Nesse caso, a solução é remover o "-"
chomp
1
chomp @ Na regra 7b da seção 2.10.10 de pubs.opengroup.org/onlinepubs/9699919799 "Se todos os caracteres anteriores a '=' formarem um nome válido (consulte Nome XBD), o token ASSIGNMENT_WORD será retornado." Seguindo o link para a seção 3.231 de pubs.opengroup.org/onlinepubs/9699919799 , encontramos "Na linguagem de comandos do shell, uma palavra que consiste apenas em sublinhados, dígitos e alfabéticos do conjunto de caracteres portátil. O primeiro caractere de um nome é nem um dígito ". Portanto, a palavra FOO-BAR=quxnão é uma atribuição de variável, pois FOO-BARnão é um nome válido.
William Pursell
2
Estou oferecendo uma recompensa para recompensar essa explicação clara a um problema sempre comum para iniciantes (bem, e também para poder encontrá-la mais rapidamente sempre que eu quiser vinculá-la: D). Obrigado por facilitar as coisas!
fedorqui 'SO stop prejudicar' 16/08
1
@fedorqui Thanks! Não estou totalmente convencido de que essa seja uma explicação clara e, com frequência, me pergunto se poderia ser mais simples.
precisa saber é o seguinte
159

Solte os espaços ao redor da =placa:

#!/bin/bash 
STR="Hello World" 
echo $STR 
Joey
fonte
9
Isso é engraçado, embora, como set foo = baré um erro comum em arquivos em lote do Windows como bem e não a linguagem lote é ridicularizado por isso ;-)
Joey
Obrigado @joey. Eu estava preso ao escrever um script de shell onde estava inicializando variáveis ​​com espaços após "=". Você salvou o meu dia
Lalit Rao
Por que o bash não aceita números no campo esquerdo? like 3 = "Hello World", queixa-se de comando não encontrado
Freedo
6

No modo interativo, tudo fica bem:

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

Obviamente (!) Como Johannes disse, não há espaço ao redor =. Caso exista algum espaço =no modo interativo, ocorrerá erros como

Nenhum comando 'str' encontrado

Arkapravo
fonte
2
Mas observe que o OP estava dizendo STR = "Hello World", portanto, essa resposta não se aplica aqui.
fedorqui 'SO stop prejudying'
@Arkapravo qual é o significado do modo interativo, é que tem algo a ver com a $marca
Kasun Siyambalapitiya
@KasunSiyambalapitiya por "modo interativo", ele significa digitar esses comandos no terminal real, não em um script.
numbermaniac
5

Eu sei que isso foi respondido com uma resposta de alta qualidade. Mas, em suma, você não pode ter espaços.

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

Não funcionou por causa dos espaços ao redor do sinal de igual. Se você fosse correr ...

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

Funcionaria

Derek Haber
fonte
2

Quando você define qualquer variável, não precisa colocar espaços extras.

Por exemplo

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

Portanto, remova os espaços:

name="Stack Overflow" 

e vai funcionar bem.

Ravi Solanki
fonte