Passar argumentos de uma função?

0

Como você faria uma função que recebesse argumentos?

function arg_example {
    arg "c"  # This is imaginary but it would return 'true' if it found the argument -c.
    did_find_arg=$?  # Get the previous function (arg)'s output.

    if [$did_find_arg == 'true']; then
        echo "Yes!"
    else
        echo "Not found."
    fi
}

# Testing
arg_example  # "Not found."
arg_example -c  # "Yes!"
arg_example -k  # "Not found."

Além disso, como você encontraria o valor de uma função de valor-chave, por exemplo, --name :

function hello {
    echo "Hello, $--name!"
}

EDIT: Eu sei como usar $1 e $2 , mas gostaria de saber como obter itens opcionais como -v ou --version .

    
por Aqua the SeaWing 26.01.2015 / 15:04

2 respostas

1

O processamento da linha de comando de uma função pode ser feito com getopts exatamente da mesma maneira que o processamento da linha de comando para um script . A única coisa a observar é que OPTIND terá que ser redefinido para 1 ou tornado local para a função:

#!/bin/bash

myfunc () {
    local OPTIND
    local do_c=0
    local do_k=0
    local opt

    while getopts 'ck' opt; do
        case $opt in
            c) do_c=1 ;;
            k) do_k=1 ;;
            *) echo 'Error in command line parsing' >&2
               return 1
        esac
    done
    shift "$(( OPTIND - 1 ))"

    if [ "$do_c" -eq 1 ]; then
        echo 'Yes!'
    else
        echo 'Not found'
    fi
}

myfunc
myfunc -c
myfunc -k
myfunc -a

O script acima produz:

Not found
Yes!
Not found
script.sh: illegal option -- a
Error in command line parsing

Relacionados:

por 25.11.2018 / 11:45
0

Extrator de argumento com nome muito simples para Bash:

#!/bin/bash

getargs()
{
  local out=""
  for argname in "$@"; do
    out="${out}local $argname=\; shift;"
  done
  printf "%s" "$out"
}

testfun()
{
  eval $(getargs a b c)
  printf "a = %s, b = %s, c = %s\n" "$a" "$b" "$c"
}

testfun "$@"                                                                                                  

Como queremos que os argumentos sejam variáveis locais no escopo dinâmico da função testfun , getargs não pode ser uma chamada de função. Em vez disso, getargs é um minúsculo compilador que traduz uma especificação de argumento como a b c na sintaxe shell , gerando o código que adicionaríamos manualmente para obter a argumento posicional em variáveis locais.

Por exemplo, a saída de

getargs a b c

é o código-fonte:

local a=$1; shift;local b=$1; shift;local c=$1; shift

quando nós eval , ele faz o que parece. No contexto do chamador, ele obtém os três primeiros argumentos posicionais em a , b e c , deslocando-os da lista de argumentos.

Agora podemos levar isso para o próximo nível e adicionar "sinos e assobios".

Para começar, o código gerado pode verificar que existem exatamente três argumentos e diagnosticar.

Poderíamos suportar argumentos opcionais: getargs a b : c (ou qualquer outro) pode significar que a e b são obrigatórios, mas c é opcional. Também poderíamos suportar argumentos finais: getargs a b : c . d poderia gerar código que obtém os dois primeiros argumentos (que são obrigatórios) nos locais a e b . Então, se um terceiro argumento estiver presente, ele entra em c . Qualquer argumento depois disso entra em d , que é uma matriz Bash.

Vou deixar isso como um exercício.

Pena que o shell não tenha um tempo de expansão de macro. A grande desvantagem disso é que o código é gerado toda vez que a função é chamada, mesmo que seja completamente estática.

Você poderia escrever algum tipo de pré-processador (por exemplo, no Awk) para transformar algum tipo de função sintática do açúcar em código shell regular.

    
por 24.07.2017 / 22:17