Eu preciso verificar a existência de um argumento de entrada. Eu tenho o seguinte script
if [ "$1" -gt "-1" ]
then echo hi
fi
eu recebo
[: : integer expression expected
Como verifico o argumento de entrada1 primeiro para ver se ele existe?
Eu preciso verificar a existência de um argumento de entrada. Eu tenho o seguinte script
if [ "$1" -gt "-1" ]
then echo hi
fi
eu recebo
[: : integer expression expected
Como verifico o argumento de entrada1 primeiro para ver se ele existe?
Respostas:
Isto é:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
A $#
variável informará o número de argumentos de entrada pelos quais o script foi passado.
Ou você pode verificar se um argumento é uma string vazia ou não é como:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
A -z
opção testará se a expansão de "$ 1" é uma sequência nula ou não. Se for uma cadeia nula, o corpo será executado.
exit 1
no final de seus ecos dentro do bloco if quando o argumento é necessário para o script funcionar. Óbvio, mas vale a pena notar pela perfeição.
programname "" secondarg third
. A $#
verificação verifica inequivocamente o número de argumentos.
if [ ! -z "$1" ]; then ...
É melhor demonstrar dessa maneira
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
Você normalmente precisa sair se tiver muito poucos argumentos.
exit 1
que você normalmente deseja e usa o [[ ]]
teste que (iirc) geralmente é mais razoável. Portanto, para as pessoas que copiam e colam cegamente o código, essa é a melhor resposta.
Em alguns casos, é necessário verificar se o usuário transmitiu um argumento para o script e, se não, retornar ao valor padrão. Como no script abaixo:
scale=${2:-1}
emulator @$1 -scale $scale
Aqui, se o usuário não passou scale
segundo parâmetro, inicio o emulador do Android -scale 1
por padrão. ${varname:-word}
é um operador de expansão. Existem outros operadores de expansão também:
${varname:=word}
qual define o indefinido em varname
vez de retornar o word
valor;${varname:?message}
que retorna varname
se está definido e não é nulo ou imprime message
e anula o script (como no primeiro exemplo);${varname:+word}
que retorna word
apenas se varname
for definido e não for nulo; retorna nulo caso contrário.${varname?message}
. O extra é :
um erro de digitação ou muda de comportamento?
: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
Tentar:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
$#
e 0
?
else
também.
foo*
) e dividir palavras (ou seja, dividir o conteúdo se o valor contiver espaço em branco). Nesse caso, não é necessário citar $#
porque esses dois casos não se aplicam. Citar o 0
também não é necessário, mas algumas pessoas preferem citar valores, pois são realmente strings e isso torna mais explícito.
Outra maneira de detectar se os argumentos foram passados para o script:
((!$#)) && echo No arguments supplied!
Observe que (( expr ))
faz com que a expressão seja avaliada de acordo com as regras da Aritmética do Shell .
Para sair na ausência de argumentos, pode-se dizer:
((!$#)) && echo No arguments supplied! && exit 1
Outra maneira (análoga) de dizer o acima seria:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let
diz:
let: let arg [arg ...]
Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
exit
que mata o meu processo zsh, eu uso return
o que não matá-lo
((!$#))
acionaria a substituição do histórico?
Somente porque há um ponto mais básico a ser destacado, acrescentarei que você pode simplesmente testar se sua string é nula:
if [ "$1" ]; then
echo yes
else
echo no
fi
Da mesma forma, se você está esperando arg count, basta testar o seu último:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
e assim por diante com qualquer arg ou var
Se você deseja verificar se o argumento existe, verifique se o número de argumentos é maior ou igual ao número do argumento de destino.
O script a seguir demonstra como isso funciona
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
produz a seguinte saída
$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments
Como um pequeno lembrete, os operadores de teste numéricos em Bash só funcionam em números inteiros ( -eq
, -lt
, -ge
, etc.)
Eu gosto de garantir que meus $ vars sejam ints
var=$(( var + 0 ))
antes de testá-los, apenas para me defender do erro "[: é necessário um número inteiro".
var=$(printf "%.0f" "$var")
pode lidar com flutuadores, mas sofre com a saída diferente de zero quando recebe uma string. Se você não se importa um awk, este método uso I parece ser o mais robusto para impor um inteiro: var=$(<<<"$var" awk '{printf "%.0f", $0}')
. Se var estiver desativado, o padrão será "0". Se var for flutuante, será arredondado para o número inteiro mais próximo. Valores negativos também são bons de usar.
validação de função bash de um liner
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
adicionar nome e uso da função
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
adicione validação para verificar se inteiro
para adicionar validação adicional, por exemplo, para verificar se o argumento passado é um número inteiro, modifique a validação de um forro para chamar uma função de validação:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
em seguida, construa uma função de validação que valide o argumento, retornando 0 em caso de sucesso, 1 em caso de falha e uma função de dado que anula o script em caso de falha
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
Ainda mais simples - basta usar set -u
set -u
certifica-se de que todas as variáveis referenciadas sejam definidas quando usadas, basta configurá-las e esquecê-las
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
[ -z "$1" ] && echo "No argument supplied"
Eu prefiro one-liners, porque são mais fáceis para mim; e é também mais rápido para o valor controlo de saída, em comparação ao usoif