Como escrever uma função no bash?

2

Estou desenhando em branco aqui. Como devo ter escrito este roteiro?

#!/bin/sh

XZY_NODES="\
vl-ocnt-1 \
vl-ocnt-2 \
vl-onet-1 \
vl-onet-2 \
vl-ocmp-1 \
vl-oomp-2 \
"

is_xyz_node () {
        host=$1
        for xyznode in $XZY_NODES
        do
                if [ $host == $xyznode ]
                then
                        return 'Y'
                fi
        done
        return 'N'
}

if [ 'Y' == $(is_xyz_node $1) ]
then
        echo "$1 is a xyz node"
else
        echo "$1 is NOT a xyz node"
fi 

Quando executo este script, recebo esta saída ...

$ ./test.sh not-xyz
./test.sh: line 22: return: N: numeric argument required
./test.sh: line 25: [: Y: unary operator expected
not-xyz is NOT a xyz node

$ ./test.sh vl-ocnt-2
./test.sh: line 19: return: Y: numeric argument required
./test.sh: line 25: [: Y: unary operator expected
vl-ocnt-2 is NOT a xyz node
    
por Red Cricket 25.07.2014 / 04:32

2 respostas

3

Você pode alterar seu código um pouco:

is_xyz_node() {
  host="$1"
  for xyznode in $XZY_NODES; do
    if [ -n "$xyznode" ] &&
       [ "$host" = "$xyznode" ]; then
      return 0
    fi
  done
  return 1
}

if is_xyz_node "$1"; then
  printf '%s is a xyz node\n' "$1"
else
  printf '%s is NOT a xyz node\n' "$1"
fi

Há algumas coisas a serem observadas:

  • return no bash requer um tipo inteiro em seu argumento opcional; isso faz com que a função saia com esse inteiro como seu status ou com o valor de $? , se não for fornecido. Então você deve usar um inteiro em vez de uma string. O inteiro deve estar entre 0 e inclusive; return 0 significa sucesso, qualquer outro valor significa falha.

  • Você deve proteger suas variáveis envolvendo-as entre aspas duplas.

  • Você deve adicionar um teste em que $xyznode não seja nulo. Como o @mikeserv apontou em seu comentário, é possível que ambos $1 e $xyznode sejam nulos, então [ '' = '' ] retorna verdadeiro.

por 25.07.2014 / 04:38
4

O retorno precisa ser um inteiro, então 1 ou 0 . Em bash , false seria 1 e true seria 0 . Então, eu substituiria 'N' por 1 e 'Y' por 0

Além disso, você também alteraria a instrução if , pois não corresponderia mais a 'Y' , você estaria correspondendo a 0 .

if [ 'Y' == $(is_xyz_node $1) ] 

deve se tornar

if is_xyz_node $1

como a função deve retornar 1 ou 0 , o que corresponde a true ou false .

    
por 25.07.2014 / 04:38

Tags