Detectar se stdin está sendo canalizado para a função shell

6

Eu tenho um número de funções de shell que eu uso no meu ambiente de linha de comando e em meus scripts de shell. Eu quero que dois deles, upper e lower , se comportem de maneira diferente dependendo se os dados estão sendo canalizados para eles. Ambas as funções estão atualmente escritas de tal forma que recebem entrada através de argumentos passados para elas.

Esta é a definição de upper :

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

Esta é a definição de lower :

lower () {
    my_echo "${1}" | tr "[:upper:]" "[:lower:]"
    return 0
}

( my_echo é um script Python que eu escrevi como um substituto para echo . Ele supostamente mostra o que quer que seja passado a ele como um argumento enquanto converte seqüências de escape em seus literais. Eu seria capaz de imprimir qualquer string sem que isso seja interpretado como uma opção, como -e para echo . A maneira como os consoles Unix funcionam, deu uma chave nessa meta, então eu a arquivei para que você possa ignorá-la.)

Existem várias encarnações passadas dessas funções. Estas são as definições das versões que operam na entrada padrão:

upper () {
    tr "[:lower:]" "[:upper:]"
}

lower () {
    tr "[:upper:]" "[:lower:]"
}

Se a função está sendo canalizada, então ela deve funcionar como descrito acima. Se não for, deve ler o primeiro parâmetro.

    
por Melab 24.07.2017 / 05:16

1 resposta

1

Seu código:

upper () {
    my_echo "${1}" | tr "[:lower:]" "[:upper:]"
    return 0
}

Para fazer isso, leia a entrada padrão se não houver argumentos:

upper () {
    ( (( $# )) && printf '%s\n' "$@" || cat ) |
    tr '[:lower:]' '[:upper:]'
}

Isso testa contra $# , o número de parâmetros posicionais e, se for zero, usa cat da leitura do fluxo de entrada padrão, caso contrário, usa printf nos argumentos posicionais. Isso é canalizado para tr .

Eu removi return 0 , já que é provável que você queira saber o status real de saída do pipeline.

Em bash , você pode fazer

upper () {
    (( $# )) && printf '%s\n' "${@^^}" || tr '[:lower:]' '[:upper:]'
}

Quando houver argumentos, isso não usará tr , mas a substituição de ${parameter^^pattern} do Bash para transformar todos os argumentos em maiúsculos (use ,, para minúsculas).

Você pode ou não querer alterar a string printf format para que seja '%s ' em vez de '%s\n' dependendo do que você deseja alcançar.

    
por 04.09.2017 / 11:13

Tags