Uso de shell de “: -” e vantagem

3

Eu encontrei esta linha em um script de shell korn:

var=${var:-/temp}

Eu posso descobrir o que está fazendo

$ var=/data
$ var=${var:-/temp}
$ echo $var
/data
$ var=
$ echo $var

$ var=${var:-/temp}
$ echo $var
/temp

Tem vantagem sobre a verificação do valor e, em seguida, a atribuição?

    
por Ajay 27.04.2015 / 23:44

4 respostas

3

É mais simplificado; você pode fazer algo em um comando simples em vez de dois (por exemplo, [[-z $var]] && var=/temp ) ou um comando complexo como

if [[-z $var ]] 
then
    var=/temp
fi

Além disso, não exige que o valor condicional ser atribuído a uma variável. Por exemplo,

#!/bin/sh
prog="$1"
# Do sanity checks & input validation here.
cc "$prog" -o "${2:-$(basename "$prog")}"

Se isso for chamado como comp foo.c , ele irá compilar foo.c e escrever a saída compilada em foo . Mas comp foo.c fu irá compilar foo.c e escreva a saída compilada em fu .

Isso se torna especialmente significativo se você quiser usar vários parâmetros com valores padrão:

some_command ${1:-default_value1} ${2:-default_value2} ${3:-default_value3} ${4:-default_value4} ${5:-default_value5} ${6:-default_value6} ${7:-default_value7} ${8:-default_value8} ${9:-default_value9}

Fazer isso de outra maneira exigiria cerca de 18 comandos para configurar os parâmetros.

Outro exemplo de como usar isso onde você não precisa atribuir o valor condicional a uma variável é um script que deseja permitir que o usuário edite um arquivo:

#!/bin/sh
    ⋮ 
file=something
    ⋮ 
"$(EDITOR:-vi}" "$file"

que chama o editor favorito do usuário (conforme especificado através da variável de ambiente EDITOR ), ou vi se o usuário não tiver especificado um.

    
por 28.04.2015 / 02:51
3

Existem três casos: var pode ter sido inicialmente não definido, vazio ou não vazio. Nos dois primeiros casos, ele é definido como /temp ; no último caso, é deixado em paz.

Outra maneira de fazer o mesmo é

: "${var:=/temp}"

Eu prefiro esse porque a cadeia de tarefas é mais clara, mas é uma questão de estética.

Em configurações normais, isso é equivalente a

if [ -z "$var" ]; then var="/temp"; fi

que é indiscutivelmente mais claro. No entanto, a sintaxe ${var:-…} ou ${var:=…} tem uma vantagem: funciona mesmo sob set -u , o que causa $var a erro se var não estiver definido. A vantagem de set -u é que facilita a captura de erros devido ao erro de digitação do nome de uma variável ou o esquecimento de defini-la sob certas condições. No entanto, ele só pode ser usado com scripts que não pressupõem que a expansão de uma variável não definida seja sempre possível.

    
por 29.04.2015 / 01:53
3

É um idioma compacto . Você pode usar inline onde os comandos são executados:

cmd "${arg1}" "${arg2}" "${arg3:-42}"

ou no início do programa (ou como primeira declaração em funções) para asseverar a interface de parâmetro (usando o comando : ):

: "${1:?} ${2:?}"

ou verifique e atribua-o às variáveis semanticamente nomeadas nas quais você opera no programa ou resp. função:

foo=${1:?} bar=${2:?} baz=${3:-42}

em que os dois primeiros argumentos (neste exemplo) são obrigatórios e o terceiro tem um valor padrão (acima de "42"), se não for fornecido.

Você também pode usar as construções relacionadas ${var:=val} (ou resp. ${var=val} ) para essa finalidade, se não os parâmetros posicionais, mas as variáveis estiverem envolvidas:

: "${foo:=${1:?}} ${bar:=${2:?}} ${baz:=${3:-42}}"

O idioma ${var:-42} também tem uma variante ${var-42} (ou seja, sem os : dois pontos) para diferenciar unset os parâmetros de vazio parâmetros; test constructos não podem diferenciar diretamente variáveis vazias de variáveis não definidas .

    
por 28.04.2015 / 03:55
1

Não é "overcheck" - é "valor padrão", em outras palavras, se o valor não for definido (ou vazio), use o valor padrão.

    
por 28.04.2015 / 00:14

Tags