Modifique argumentos bash se apenas um argumento for definido

2

Eu criei um script com o padrão getopt magic , para poder chamar o script com

batman-connect -c ffki

Como posso adicionar uma opção para chamar esse script com apenas uma opção sem traço?

batman-connect ffki

então Ele interpretará essa única opção como o segundo argumento para -c ?

De acordo com esta resposta , tentei:

if [ $@ = "ffki" ]; then
  set -- "-c $@"
fi

Mas isso dá um erro, porque acho que essa linha no meu script mude de volta:

# Execute getopt on the arguments passed to this program, identified by the special character $@
PARSED_OPTIONS=$(getopt -n "$0"  -o hsrvVi:c: --long "help,start,restart,stop,verbose,vv,version,interface:,community:"  -- "$@")

Eu não gosto de reorganizar todo o meu script, então existe um simples one-liner para apenas definir o primeiro argumento para "-c" e o segundo para "ffki"?

    
por rubo77 07.09.2014 / 09:17

4 respostas

1

Você pode fazer algo parecido com

if [ $# = 1 ]; then
    # do whatever you'd do when there is only one argument
else
    # do the getopt bits
fi
# do what you'd do in either case

Se -c é o único switch que você quer suportar, então você não precisa getopt e pode fazer algo assim:

#!/bin/bash

usage() {
    echo "Usage: $0 [ -c ] arg" >&2
    exit 1
}

if [ $# = 2 ]; then
    if [ $1 = "-c" ]; then
        shift
        c_switch_value="$1"
    else
        usage
    fi
elif [ $# = 1 ]; then
    c_switch_value="$1"
else
    usage
fi

Se isso é mais legível, é discutível.

    
por 07.09.2014 / 09:27
1

Eu adicionei logo no início deste script:

if [ $# = 1 ]; then
  # If there is only one argument, replace the current process with the new invocation of the script
  # the only option will be used as -c option
  exec "$0" -c "$@"
fi

Isso não responde à pergunta inicial, mas é uma solução alternativa que funciona no meu caso especial.

    
por 07.09.2014 / 09:39
1
if [ $@ = "ffki" ]; then

O comando na cláusula if expande para [ seguido pela lista de expansões curinga das palavras que compõem os parâmetros posicionais seguidas pelas palavras = ffki ] . De um modo geral, $VAR não significa “o valor de VAR ” quando está fora de aspas duplas, isso significa “dividir o valor de VAR em palavras separadas e interpretá-las como globs”. Veja Por que meu script de shell engasgar com espaço em branco ou outros caracteres especiais?

Além disso, "$@" é um caso especial: expande-se para a lista de parâmetros posicionais (sem expansão adicional), não para uma única palavra (apesar das aspas). Você pode usar "$*" , que se expande para uma única palavra composta de parâmetros posicionais separados por um espaço (mais precisamente, pelo primeiro caractere do valor de IFS ). Então, para testar se existe um único parâmetro posicional cujo valor seja ffki , você pode usar

if [ "$*" = "ffki" ]; then

Como alternativa, você pode contar o número de parâmetros posicionais e testar seu valor individualmente. Isso seria necessário se você quisesse permitir valores contendo espaços, por exemplo.

if [ $# -eq 1 ] && [ "$1" = "ffki" ]; then

Para alterar os parâmetros posicionais, você estava próximo: use o set builtin e passe o novo conjunto de parâmetros posicionais como argumentos separados. Se houver o risco de o primeiro parâmetro começar com - , use set -- … para que não seja interpretado como uma opção.

if [ "$*" = "ffki" ]; then
  set -- -c "ffki"
fi
    
por 07.09.2014 / 23:44
0

Você provavelmente quer algo assim:

# getopt code that sets "$c_value" goes here ...
# ... then
if [[ -z $c_value ]] && (( $# > 0 )); then
    c_value=$1
    shift
fi
    
por 07.09.2014 / 10:52