8. Dando mais flexibilidade a um script rc.d

Quando chamado durante a inicialização ou desligamento, um script rc.d deve agir em todo o subsistema pelo qual é responsável. Por exemplo, /etc/rc.d/netif deve iniciar ou parar todas as interfaces de rede descritas por rc.conf(5). Qualquer tarefa pode ser indicada exclusivamente por um único argumento de comando, como start ou stop. Entre a inicialização e o desligamento, os scripts rc.d ajudam o administrador a controlar o sistema em execução, e é quando surge a necessidade de mais flexibilidade e precisão. Por exemplo, o administrador pode querer adicionar as configurações de uma nova interface de rede ao rc.conf(5) e então iniciá-lo sem interferir o funcionamento das interfaces existentes. Da próxima vez, o administrador pode precisar desligar uma única interface de rede. No espírito da linha de comando, o respectivo script rc.d solicita um argumento extra, o nome da interface.

Felizmente, rc.subr(8) permite passar qualquer número de argumentos para os métodos do script (dentro dos limites do sistema). Devido a isso, as alterações no próprio script podem ser mínimas.

Como o rc.subr(8) pode obter acesso aos argumentos de linha de comando extra. Deveria pegá-los diretamente? Não por qualquer meio. Primeiro, uma função sh(1) não tem acesso aos parâmetros posicionais de seu chamador, mas o rc.subr(8) é apenas uma despedida de tais funções. Em segundo lugar, a boa maneira de rc.d determina que é para o script principal decidir quais argumentos devem ser passados para seus métodos.

Portanto, a abordagem adotada por rc.subr(8) é a seguinte: run_rc_command transmite todos os seus argumentos, mas o primeiro um para o respectivo método na íntegra. O primeiro, omitido, argumento é o nome do próprio método: start,stop, etc. Ele será deslocado por run_rc_command, então o que é $2 na linha de comando original será apresentado como $1 ao método, e assim por diante.

Para ilustrar essa oportunidade, vamos modificar o script fictício primitivo para que suas mensagens dependam dos argumentos adicionais fornecidos. Aqui vamos nós:

#!/bin/sh

. /etc/rc.subr

name="dummy"
start_cmd="${name}_start"
stop_cmd=":"
kiss_cmd="${name}_kiss"
extra_commands="kiss"

dummy_start()
{
        if [ $# -gt 0 ]; then1
                echo "Greeting message: $*"
        else
                echo "Nothing started."
        fi
}

dummy_kiss()
{
        echo -n "A ghost gives you a kiss"
        if [ $# -gt 0 ]; then2
                echo -n " and whispers: $*"
        fi
        case "$*" in
        *[.!?])
                echo
                ;;
        *)
                echo .
                ;;
        esac
}

load_rc_config $name
run_rc_command "$@"3

Quais mudanças essenciais podemos notar no script?

1

Todos os argumentos digitados após start podem terminar como parâmetros posicionais para o respectivo método. Podemos usá-los de qualquer maneira de acordo com nossa tarefa, habilidades e fantasia. No exemplo atual, apenas passamos todos eles para echo(1) como uma cadeia na linha seguinte - note $* entre aspas duplas. Aqui está como o script pode ser chamado agora:

# /etc/rc.d/dummy start
Nothing started.
# /etc/rc.d/dummy start Hello world!
Greeting message: Hello world!

2

O mesmo se aplica a qualquer método que nosso script forneça, não apenas a um método padrão. Nós adicionamos um método customizado chamado kiss, e ele pode tirar proveito dos argumentos extras da mesma forma que o start tira. Por exemplo:

# /etc/rc.d/dummy kiss
A ghost gives you a kiss.
# /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...
A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...

3

Se quisermos apenas passar todos os argumentos extras para qualquer método, podemos simplesmente substituir "$@" por "$ 1" na última linha do nosso script, onde invocamos o run_rc_command.

Importante:

Um programador sh(1) deve entender a diferença sutil entre $* e $@ como as formas de designar todos os parâmetros posicionais. Para sua discussão aprofundada, consulte um bom manual sobre programação de scripts sh(1). Não use estas expressões até que você as compreenda completamente, porque o uso incorreto delas resultará em scripts inseguros e contendo bugs.

Nota:

Atualmente, o run_rc_command pode ter um bug que o impede de manter os limites originais entre os argumentos. Ou seja, argumentos com espaços em branco incorporados podem não ser processados corretamente. O bug deriva do uso inadequado de $*.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.