Quando os espaços ao redor do sinal = são proibidos?

9

Eu sei que em ~ / .bashrc não se deve colocar espaços em torno de =sinais na atribuição:

$ tail -n2 ~/.bashrc 
alias a="echo 'You hit a!'"
alias b = "echo 'You hit b!'"

$ a
You hit a!

$ b
b: command not found

Estou revisando o arquivo de configuração do MySQL /etc/my.cnfe encontrei o seguinte:

tmpdir=/mnt/ramdisk
key_buffer_size = 1024M
innodb_buffer_pool_size = 512M
query_cache_size=16M

Como posso verificar se os espaços ao redor dos =sinais não são um problema?

Observe que esta pergunta não é específica para o /etc/my.cnfarquivo, mas para os arquivos de configuração * NIX em geral. Minha primeira inclinação é o RTFM, mas, na verdade, man mysqlnão menciona o problema e, se eu precisar procurar online para cada caso, nunca chegarei a lugar algum. Existe alguma convenção ou maneira fácil de verificar? Como pode ser visto, várias pessoas editaram esse arquivo (convenções diferentes para =sinais) e não posso forçá-las a não usar espaços, nem enlouquecer verificando tudo o que pode ter sido configurado e pode ou não estar correto.

EDIT: Minha intenção é garantir que os arquivos atualmente configurados sejam feitos corretamente. Ao configurar os arquivos eu mesmo, aceito a convenção de qualquer que seja o mantenedor do pacote.

dotancohen
fonte
2
Não existe "* arquivos de configuração do NIX em geral". Se eu quiser permitir espaços no meu arquivo de configuração, escreverei meu programa para permiti-los. Se eu quiser que meu arquivo de configuração use dois pontos ou tubos em vez de sinais de igual, escreverei meu programa para usá-los. O Bash não requer espaços. O Mysql permite.
Hymie

Respostas:

3

Eu responderei isso de uma maneira mais geral - analisando um pouco toda a " experiência de aprendizado do Unix ".

No seu exemplo, você usa duas ferramentas e vê que o idioma é semelhante. Não está claro quando usar o que exatamente. Claro que você pode esperar que exista uma estrutura clara , então você nos pede para explicar isso.
O caso com o espaço ao redor =é apenas um exemplo - existem muitos casos semelhantes, mas muito ruins.
Não tem que ser uma lógica nisso, certo ?!

As regras de como escrever código para alguma ferramenta , shell, banco de dados, etc, dependem apenas do que essa ferramenta específica exige .

Isso significa que as ferramentas são completamente independentes , tecnicamente. A relação lógica que acho que você espera simplesmente não existe .

A semelhança óbvia das linguagens que você está vendo não faz parte da implementação do programa . A semelhança existe porque os desenvolvedores concordaram em fazê-lo quando o escreveram para um programa específico. Mas os humanos podem concordar apenas parcialmente .

A relação que você está vendo é uma coisa cultural - não faz parte da implementação , nem na definição da linguagem .



Então, agora que lidamos com a teoria, o que fazer na prática?

Um grande passo é aceitar que a consistência que você esperava não existe - o que é muito mais fácil ao entender os motivos - espero que a parte da teoria ajude com isso.

Se você possui duas ferramentas, que não usam a mesma linguagem de configuração (por exemplo, os dois scripts de bash), conhecer os detalhes da sintaxe de uma não ajuda muito na compreensão da outra;
Então, de fato, você terá que procurar detalhes de forma independente . Certifique-se de saber onde encontra a documentação de referência para cada um.

No lado positivo, há alguma consistência em que você não esperava: no contexto de uma única ferramenta (ou ferramentas diferentes usando a mesma linguagem), você pode ter certeza de que a sintaxe é consistente.
No seu mysqlexemplo, isso significa que você pode assumir que todas as linhas têm a mesma regra. Portanto, a regra é "o espaço antes e depois não= é relevante ".

Existem grandes diferenças na dificuldade de aprender ou usar a linguagem de configuração ou script de uma ferramenta.
Pode ser algo como " Listar valores foo no cmd-foo.conf, um por linha".
Pode ser uma linguagem de script completa que também é usada em outros lugares. Então você tem uma ferramenta poderosa para escrever a configuração - e, em alguns casos, isso é legal; em outros, você realmente precisa disso.
Ferramentas complexas ou grandes famílias de ferramentas relacionadas às vezes usam apenas uma sintaxe de arquivo de configuração especial muito complexa - (alguns exemplos famosos são sendmaile vim).
Outros usam um script geralidioma como base e estenda esse idioma para atender às necessidades especiais , algumas vezes de maneiras complexas, conforme o idioma permitir. Esse seria um caso muito específico de uma linguagem específica de domínio ( DSL ) .

Volker Siegel
fonte
Aceita, pois esta é a resposta que mais aborda a resposta do ponto de vista da pergunta. Obrigado!
dotancohen
20

O Bash interpretará uma linha que possui texto seguido de a =como uma atribuição a uma variável, mas interpretará uma linha que possui texto seguido de um espaço como um comando com argumento.

var=assignment vs command =argument

Os scripts Bash funcionam com o princípio de que tudo no script é como se você o tivesse digitado na linha de comando.

Nos arquivos de configuração que não são interpretados por bash(ou outro shell), serão determinados pelo analisador usado para ler o arquivo de configuração. Alguns analisadores ocupam espaços, outros não. Cabe à aplicação nesse caso. Pessoalmente, concordo com qualquer convenção que o arquivo de configuração padrão tenha usado.

Lawrence
fonte
Obrigado. Estou preocupado com a forma de verificar os arquivos existentes, agora e no futuro, que podem ter sido configurados por outros tipos de devops. Ao configurar os arquivos, eu vou com a convenção de qualquer que seja o mantenedor de pacotes, como você sugere. Eu editei a pergunta para esclarecer.
dotancohen
1
Eu acho que se você estiver verificando os arquivos existentes, eu verificaria a documentação do produto e a usaria como exemplo. Supondo que você tenha documentação e não seja um aplicativo personalizado. Se fosse um aplicativo personalizado, eu ficaria com o que já estava lá. "Se não está quebrado, não conserte"
Lawrence
Infelizmente, alguns deles estão falidos. É por isso que estou perguntando!
dotancohen
Em conchas, nunca use espaços em torno de iguais. Em qualquer coisa que não seja uma concha, use sempre espaços. Você pode auditar arquivos existentes usando grep: 'grep "[^] = [^]" / etc / *' para encontrar arquivos com um = que não possui espaços.
QRIS
2
@dotancohen (1.) Para qualquer arquivo de configuração, deve haver pelo menos uma configuração que seria bastante fácil de verificar se está quebrada. Se um arquivo de configuração permite espaços ou não, deve fazê-lo de forma consistente o tempo todo. (2.) Você sempre pode baixar um aplicativo e verificar as configurações padrão fornecidas. (3.) Você sempre pode deixar espaços completamente fora. a = bnem sempre é aceitável, mas a=bsempre deve funcionar.
Alquimista de dois bits
4

O .bashrc nada mais é do que um arquivo de configuração para o bash, assim como my.cnf, php.ini, httpd.conf ou uma lista do launchd. Cada um tem sua própria sintaxe, desde a atribuição de espaço sem espaço do bash até a sopa de tags XML do launchd (também há uma versão binária: -O)

Não existem convenções firmes e você já descobriu a Diretiva Principal do Unix: Leia o Manual Fino .

Paulo
fonte
1
.bashrcnão é um arquivo de configuração para o bash. .bashrcé um script de shell que o bash é executado toda vez que um processo do bash é iniciado. Ele pode ser usado para configurar o bash, mas também pode fazer todo tipo de coisa: é um script, não um arquivo de configuração.
284 Josh
3

Alguns programas oferecem uma verificação do arquivo de configuração, por exemplo:

postfix check

Caso contrário, você poderá obter os arquivos de configuração originais dos repositórios e compará-los com diff ao atual.

user78568
fonte
Na verdade, isso parece realmente resolver o problema principal. Obrigado!
dotancohen
2

Os espaços ao redor do =sinal sempre são problemáticos quando você faz uma tarefa bash. Não há exceção aqui, você deve remover todos os espaços ao redor =se quiser obter uma atribuição simples válida (sem expansão, sem aritmética, sem atribuição de matriz) bash.

Para o arquivo de configuração, porque cada software possui seu próprio analisador para analisar seu arquivo de configuração, bashnão possui relacionamento. Você deve ler a documentação para saber qual sintaxe é permitida no arquivo de configuração.

Um exemplo é mysql, em seu script init /etc/init.d/mysqld, ele possui um analisador para my.cnf:

# Try to find basedir in /etc/my.cnf
  conf=/etc/my.cnf
  print_defaults=
  if test -r $conf
  then
    subpat='^[^=]*basedir[^=]*=\(.*\)$'
    dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
    for d in $dirs
    do
      d=`echo $d | sed -e 's/[  ]//g'`
      if test -x "$d/bin/my_print_defaults"
      then
        print_defaults="$d/bin/my_print_defaults"
        break
      fi
      if test -x "$d/bin/mysql_print_defaults"
      then
        print_defaults="$d/bin/mysql_print_defaults"
        break
      fi
    done
  fi
cuonglm
fonte
Há uma exceção em (( var = 12 ))ou var=( value )ou $((var = 12))ou${var[foo = 12]}
Stéphane Chazelas
@ StéphaneChazelas: Não mencionou esses casos nesta pergunta, adicione informações. Obrigado.
21814 cu Cullm