Devo verificare l'esistenza di un argomento di input. Ho il seguente script
if [ "$1" -gt "-1" ]
then echo hi
fi
ottengo
[: : integer expression expected
Come controllo prima l'argomento input1 per vedere se esiste?
Devo verificare l'esistenza di un argomento di input. Ho il seguente script
if [ "$1" -gt "-1" ]
then echo hi
fi
ottengo
[: : integer expression expected
Come controllo prima l'argomento input1 per vedere se esiste?
Risposte:
È:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
La $#
variabile ti dirà il numero di argomenti di input che lo script è stato passato.
Oppure puoi verificare se un argomento è una stringa vuota o meno:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
Lo -z
switch verificherà se l'espansione di "$ 1" è una stringa nulla o meno. Se è una stringa nulla, il corpo viene eseguito.
exit 1
alla fine del tuo echos all'interno del blocco if quando è richiesto l'argomento affinché lo script funzioni. Ovvio, ma vale la pena notare per completezza.
programname "" secondarg third
. Il $#
controllo controlla in modo inequivocabile il numero di argomenti.
if [ ! -z "$1" ]; then ...
È meglio dimostrare in questo modo
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
Normalmente devi uscire se hai troppi argomenti.
exit 1
che di solito vuoi e usa il [[ ]]
test che (iirc) è di solito più ragionevole. Quindi, per le persone che copiano ciecamente il codice incollato questa è la risposta migliore.
In alcuni casi è necessario verificare se l'utente ha passato un argomento allo script e, in caso contrario, tornare a un valore predefinito. Come nello script seguente:
scale=${2:-1}
emulator @$1 -scale $scale
Qui se l'utente non ha passato scale
il secondo parametro, avvio l'emulatore Android -scale 1
per impostazione predefinita. ${varname:-word}
è un operatore di espansione. Esistono anche altri operatori di espansione:
${varname:=word}
che imposta il non definito varname
invece di restituire il word
valore;${varname:?message}
che restituisce varname
se è definito e non è nullo o stampa message
e interrompe lo script (come nel primo esempio);${varname:+word}
che restituisce word
solo se varname
è definito e non è nullo; restituisce null altrimenti.${varname?message}
. L'extra è :
un refuso o cambia comportamento?
: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
Provare:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
$#
e 0
?
else
anche questo.
foo*
) e la suddivisione delle parole (ovvero la divisione del contenuto se il valore contiene spazi bianchi). In questo caso non è necessario citare $#
perché entrambi questi casi non si applicano. Anche la citazione di 0
non è necessaria, ma alcune persone preferiscono citare i valori poiché sono veramente stringhe e questo lo rende più esplicito.
Un altro modo per rilevare se gli argomenti sono stati passati allo script:
((!$#)) && echo No arguments supplied!
Si noti che (( expr ))
causa l'espressione da valutare secondo le regole dell'aritmetica della shell .
Per uscire in assenza di argomenti, si può dire:
((!$#)) && echo No arguments supplied! && exit 1
Un altro modo (analogo) per dire quanto sopra sarebbe:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let
dice:
let: let arg [arg ...]
Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
exit
quale uccide il mio processo zsh, io uso quello return
che non lo uccide
((!$#))
innescare la sostituzione della storia?
Solo perché c'è un altro punto base da sottolineare aggiungo che puoi semplicemente testare la tua stringa è nulla:
if [ "$1" ]; then
echo yes
else
echo no
fi
Allo stesso modo, se ti aspetti un conteggio degli arg, prova il tuo ultimo:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
e così via con qualsiasi arg o var
Se desideri verificare se esiste l'argomento, puoi verificare se il numero di argomenti è maggiore o uguale al numero dell'argomento di destinazione.
Il seguente script dimostra come funziona
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
produce il seguente output
$ ./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
Come un piccolo promemoria, gli operatori di verifica numerici in Bash funzionano solo su numeri interi ( -eq
, -lt
, -ge
, etc.)
Mi piace assicurarmi che i miei $ var siano ints di
var=$(( var + 0 ))
prima di testarli, giusto per difendermi dall'errore "[: integer arg required".
var=$(printf "%.0f" "$var")
può gestire i float ma soffre dell'uscita diversa da zero quando viene data una stringa. Se non ti dispiace un awk, questo uso metodo che sembra essere il più robusto di far rispettare un numero intero: var=$(<<<"$var" awk '{printf "%.0f", $0}')
. Se var non è impostato, il valore predefinito è "0". Se var è un float, viene arrotondato al numero intero più vicino. Anche i valori negativi possono essere utilizzati.
una convalida della funzione bash di linea
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
aggiungi il nome e l'utilizzo della funzione
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
aggiungi la validazione per verificare se intero
per aggiungere ulteriore convalida, ad esempio per verificare se l'argomento passato è un numero intero, modificare la convalida di una riga per chiamare una funzione di convalida:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
quindi, costruisci una funzione di validazione che convalida l'argomento, restituendo 0 in caso di successo, 1 in caso di fallimento e una funzione die che interrompe lo script in caso di fallimento
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
Ancora più semplice: basta usare set -u
set -u
si assicura che ogni variabile referenziata sia impostata quando viene usata, quindi basta impostarla e dimenticarla
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
[ -z "$1" ] && echo "No argument supplied"
Preferisco i liner singoli, poiché sono più facili per me; ed è anche più veloce controllare il valore di uscita, rispetto all'utilizzoif