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 / 456698
Accepted
Jim
Jim
Asked: 2018-07-17 23:40:05 +0800 CST2018-07-17 23:40:05 +0800 CST 2018-07-17 23:40:05 +0800 CST

Passando um sinalizador booleano para uma função?

  • 772

Eu tenho uma função que dependendo de um argumento onde a funcionalidade muda.
Eu sei que posso fazer:

function foo {  
  PARAM1=$1  
  PARAM2="$2"  
  VAR=$3  
  if[[ -z "$VAR" ]]; then  
   # code here  
  else  
   # other code here  
  fi  
}  

Eu queria saber se existe uma abordagem mais apropriada para o bash. Isso funcionaria, mas eu não gostaria de ter algo como

foo "x" "y" "blah"  
foo "x" "y" "true"  
foo "y" "y" "1"

tudo para ser equivalente.

Existe uma abordagem mais adequada ao Bash?

bash shell-script
  • 3 3 respostas
  • 24079 Views

3 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2018-07-18T00:36:40+08:002018-07-18T00:36:40+08:00

    Você pode fornecer uma opção de linha de comando para sua função. Usar opções de linha de comando sem argumentos é uma maneira comum de fornecer valores binários/booleanos ("on/off", "true/false", "enable/disable") para scripts de shell, funções de shell e utilitários em geral.

    foo () {
        local flag=false
        OPTIND=1
    
        while getopts 't' opt; do
            case $opt in
                t) flag=true ;;
                *) echo 'Error in command line parsing' >&2
                   exit 1
            esac
        done
        shift "$(( OPTIND - 1 ))"
    
        local param1="$1"
        local param2="$2"
    
        if "$flag"; then
            # do things for "foo -t blah blah"
        else
            # do things for "foo blah blah"
        fi
    }
    

    A opção -tfunciona como um sinalizador booleano para o usuário. Usá-lo definiria flagdentro da função para true(alterando-o de seu valor padrão de false). A -topção seria usada como o primeiro argumento para a função.

    A chamada da função seria feita usando

    foo "some value" "some other value"
    

    ou

    foo -t "some value" "some other value"
    

    onde a última chamada definiria a flagvariável na função para true.

    • 10
  2. ctrl-alt-delor
    2018-07-18T00:26:23+08:002018-07-18T00:26:23+08:00

    No geral

    Em geral, passar booleanos para funções, em qualquer linguagem, é ilegível. por exemplo calculate_interest 5y 4% true. O leitor fica se perguntando o que é verdade.

    Portanto, use uma enumeração: { per_month, per_year }. Agora você pode fazer calculate_interest 5y 4% per_year. Isso é mais legível.

    Na festa

    O Bash não é tipado estaticamente (ou fortemente tipado, ou tem muito de um sistema de tipos), então você pode passar muitos valores diferentes. Um vai liderar desta forma, os outros não. Não é desejável ter muitos valores diferentes que levam ao mesmo caminho.

    Portanto, adicione código para verificar se a entrada é um dos dois valores aceitáveis. Faça isso no início da função, você não quer sair da metade do caminho para fazer algo.

    O que fazer se você tiver que chamar uma função que recebe um booleano

    Então alguém não seguiu meu conselho, e você tem que chamar uma função que recebe um booleano. O que você pode fazer para tornar seu código legível?

    • Se a linguagem (como Python) permitir argumentos nomeados, por exemplo calculate_interest 5y 4% per_year=True, use-os. Vai ajudar, mas não lhe diz o significado de calculate_interest 5y 4% per_year=False.
    • Se a linguagem não tiver argumentos nomeados, as únicas opções serão viver com código ilegível (não uma opção) ou envolver as funções em funções alfabetizadas.
    • 3
  3. nxnev
    2018-07-19T03:32:35+08:002018-07-19T03:32:35+08:00

    Eu recomendo seguir um formato como este:

    foo() {
      # Limit scope of variables
      local 'opt1' 'opt2' 'opt3' 'operands'
    
      # Default values
      opt1='default1'
      opt2='default2'
      opt3='false'
      operands=()
    
      # Arguments handling
      while (( ${#} > 0 )); do
        case "${1}" in
          ( '--opt1='* ) opt1="${1#*=}" ;;           # Handles --opt1
          ( '--opt2='* ) opt2="${1#*=}" ;;           # Handles --opt2
          ( '--opt3='* ) opt3="${1#*=}" ;;           # Handles --opt3
          ( '--' ) operands+=( "${@:2}" ); break ;;  # End of options
          ( '-'?* ) ;;                               # Discard non-valid options
          ( * ) operands+=( "${1}" )                 # Handles operands
        esac
        shift
      done
    
      ...
    }
    

    Dessa forma, a função será mais robusta e legível:

    $ foo
    Options:
      opt1: [default1]
      opt2: [default2]
      opt3: [false]
    
    $ foo --opt1='value1' --opt2='value2' --opt3='true' 'foo' 'bar' 'baz'
    Options:
      opt1: [value1]
      opt2: [value2]
      opt3: [true]
    Operands:
      1: [foo]
      2: [bar]
      3: [baz]
    

    Prós:

    • Fácil de ler e compreender.
    • A sintaxe é semelhante a qualquer utilitário de linha de comando típico.
    • É fácil adicionar mais opções sem quebrar a compatibilidade.

    Contras:

    • Pode ser um exagero para scripts pequenos e simples.
    • Difícil escrever um equivalente portátil e compatível com POSIX que também lide com opções e operandos longos.
    • 3

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • MySQL Select com função IN () com array bash

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

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

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 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

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 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
    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
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +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
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +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