AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 677735
Accepted
MountainX
MountainX
Asked: 2021-11-16 22:29:30 +0800 CST2021-11-16 22:29:30 +0800 CST 2021-11-16 22:29:30 +0800 CST

o que é essa sintaxe zsh? nome() verdadeiro

  • 772

Estou assumindo que o seguinte bloco representa uma função, mas pode não ser:

mounted()true
if
  ...
fi ... && mounted

Eu quero entender o que é essa construção. Não encontrei sintaxe semelhante no cabeçalho de funções em zsh

Um trecho mais completo do código real é:

#! /bin/zsh -p

# leaving out a section...

tmpdir=$(mktemp -d) || exit

mounted()true
if
  mount "$type[@]" -o "${(j[,])opts}" -- "$dev" "$tmpdir"
then
  mount --bind -- "$tmpdir/$subdir" "$dest" || mounted()false
  umount -- "$tmpdir"
fi && rmdir -- "$tmpdir" && mounted

Assim que eu entender, vou converter todo o script zsh para uma linguagem com a qual estou mais familiarizado. Eu poderia convertê-lo em bash como uma etapa intermediária.

zsh
  • 1 1 respostas
  • 487 Views

1 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2021-11-16T22:50:39+08:002021-11-16T22:50:39+08:00

    Essa é a sintaxe do shell Bourne (dos anos 80) para definir uma função, não é específica do zsh.

    No shell Bourne, uma função é definida colocando -se functionName()na frente de um comando¹.

    Assim name() truedefine uma função chamada name com o truecomando simples como seu corpo.

    $ name()true
    $ type name
    name is a shell function
    

    Esse é o caso em quase todos os shells do tipo Bourne (ksh, ash, dash, bosh, pdksh, mksh, zsh...). Uma exceção notável é bash² (o shell GNU) que inicialmente só permitia que um grupo de comandos ( { ...; }) fosse o corpo de uma função e posteriormente o alterasse para qualquer comando composto como o POSIX requer para a shlinguagem .

    Então, em bash, você precisaria de name()((1))or name()[[ . ]]( (( ... ))e [[ ... ]]—construtos emprestados de ksh— sendo considerados comandos compostos lá), ou name() { true; }onde o corpo da função é um grupo de comandos com apenas um comando simples dentro.

    Observe que kshfoi o shell que introduziu as funções pela primeira vez, embora com uma sintaxe diferente: function name { body; }. zshsuporta a sintaxe Korn e Bourne e possui extensões próprias.

    Em zshver info zsh function, o que deve levar você à parte sobre a palavra- functionchave Korn para a sintaxe das definições de funções. Uma extensão de zshé que você pode definir mais de uma função de uma vez com o mesmo corpo e usar qualquer string como o nome da função³:

    vrai 1 + $'\1' () true
    faux 0 - $'\0' '' () false
    

    Para definir algumas funções diferentes que chamam trueou falsesem argumentos.

    Se você omitir o nome da função, isso se torna uma função anônima, que pode receber argumentos e é invocada no local:

    () { echo There are $# non-hidden txt files; } *.txt(N)
    

    (embora por razões óbvias, para que essa função anônima possa receber argumentos, seu corpo não pode ser um comando simples).

    Em zsh, as funções também são disponibilizadas através do $functionsarray associativo especial onde as teclas são os nomes das funções e valorizam o código no corpo. Então functions[name]=trueé outra maneira de definir a namefunção.


    Agora, usar funções para armazenar um valor booleano não é algo que você vê com muita frequência, mas se você parar para pensar sobre isso por um minuto, faz bastante sentido.

    Na linguagem C, por exemplo, as construções if/ whileou os operadores lógicos &&/ ||atuam em números. if (condition) somethingfaz somethingse conditionfor um número diferente de zero. awkou perlque são linguagens semelhantes a C estendem isso para conditionserem definidas ou serem strings não vazias.

    Mas os shells estão antes de todos os intérpretes de linha de comando. No shell, tudo é um comando. if/ whilee &&/ ||na maioria dos shells atuam em comandos. if condition; then something; fifaz somethingse o conditioncomando for bem-sucedido.

    falsee truesão comandos de constantes booleanas (incorporados na maioria dos shells) que sempre falham / são bem-sucedidos, respectivamente, então são os óbvios para representar valores booleanos. E as funções são a estrutura de dados mais apropriada para armazenar comandos (ou código shell em geral).

    aliases (que muitos consideram uma herança quebrada do csh, um shell que (como o Bourne shell inicialmente) não tinha funções) não funcionaria aqui, pois os aliases são expandidos no momento em que o código que os contém é lido, não em tempo de execução. Por exemplo em:

    alias name=false
    myfunction()
      if name; then
        something
      fi
    alias name=true
    myfunction
    

    O corpo da função realmente conterá if false; then...porque o namealias foi expandido no momento em que o código para definir a função foi lido, não no momento em que a função é executada.

    Pode-se armazenar o código em uma variável em vez de uma função:

    name=true name=false
    if eval " $name"; then
      ...
    fi
    

    Onde testamos o sucesso do evalcomando que é instruído a interpretar o código em $name4 . Observe que, nesse caso, um vazio / indefinido (exceto com a nounsetopção) $nameproduz true .

    Ou poderíamos fazer (e é o que geralmente faço em sh/ bashscripts):

    name=true name=false
    if "$name"; then
      ...
    fi
    

    Onde executamos o comando cujo nome está armazenado $namesem argumentos.

    Ou:

    name=(true) name=(false)
    if "${name[@]}"; then
      ...
    fi
    

    Onde armazenamos os argumentos de um comando simples em um $name array de variáveis.

    Pessoas acostumadas a linguagens do tipo C podem querer armazenar os booleanos como variáveis ​​inteiras e executar um comando como [/ testou exprpara testar o valor de inteiros quando convertidos de suas representações textuais:

    false=0 true=1
    name=$false name=$true
    
    if expr "$name" > /dev/null; then
      ...
    fi
    if [ "$name" -ne 0 ]; then
      ...
    fi
    

    Em shells semelhantes a Korn (inclui bashe zsh), você pode usar a ((...))construção que avalia expressões aritméticas semelhantes a C e retorna sucesso se isso resultar em um número diferente de zero (mesmo NaN).

    false=0 true=1
    name=$false name=$true
    # or even:
    name=false name=true
    if (( name )); then
      ...
    fi
    

    Você também pode executar um comando que compara strings (como [/ test/ exprnovamente) ou faz correspondência de padrões como essa outra [[ string = pattern ]]construção semelhante a Korn:

    name=true name=false
    if [ "$name" = true ]; then
      ...
    fi
    

    (isso soa tão estranho para mim quanto fazer um if (strcmp(name, "true") == 0)...em C).

    Ou mesmo se você gostasse, com um teste awk/ perl-like para uma variável definida.

    unset -v name # unset = false
    name=         #   set = true
    if [ -n "${name+true}" ]; then
      ...
    fi
    

    ¹ Houve um bug no shell Bourne (não em seus clones/derivativos 5 ) embora isso não funcionasse corretamente se você usasse um comando simples com redirecionamentos como o corpo da função, e é provavelmente por isso que o POSIX requer apenas comandos compostos ser suportado como corpo de funções.

    ² yash(escrito para a especificação POSIX), posh(com base, pdkshmas escrito para ajudar a verificar a conformidade com o padrão, portanto, com a maioria das extensões do padrão removidas, incluindo aquela) são duas outras exceções

    ³ que é consistente com o fato de que comandos externos e argumentos de comando podem ser qualquer string, pois os arquivos podem conter qualquer string (embora um nome de arquivo não possa estar vazio e nomes de arquivo/argumentos não possam conter bytes NUL). No shell Bourne, os nomes de funções e variáveis ​​compartilhavam o mesmo namespace (não era possível definir uma função e uma variável com o mesmo nome) e os nomes das funções tinham as mesmas limitações que os nomes das variáveis.

    4 com um espaço prefixado para correção, pois algumas evalimplementações não suportam --marcar o fim das opções

    5 zsh, costumava ter seus próprios problemas quando os redirecionamentos eram usados ​​no corpo de uma função, a maioria dos quais foi corrigida. Mas mesmo agora, e conforme declarado explicitamente na documentação, em f() { cmd; } < $1, (no caso especial em que o corpo é um grupo de comandos com redirecionamentos) isso $1não se refere ao $1no escopo da função, mas ao $1do chamador que em essa instância a torna não compatível com POSIX. Isso não se aplica a comandos simples ou outros tipos de comandos compostos (que são zshencapsulados internamente em {...}).

    • 11

relate perguntas

  • Listar arquivos que não possuem outro arquivo com sufixo

  • Em que circunstâncias o executável encontrado primeiro no caminho não será usado

  • Symlinking para todos os arquivos de ponto e diretórios

  • Como incrementar uma variável nomeada dinamicamente em `zsh`

  • Por que não consigo definir uma variável somente leitura chamada path no zsh?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve