22

I would like to check if the first command line argument ($1) has an minimum amount of 10 characters and if it is empty.

The script is called as:

./myscript.sh 2018-08-14

I tried this but it doesn't work

timestamp="$1"

# check if command line argument is empty or not present
if [ "$1" == "" ] || [ $# -gt 1 ]; then
        echo "Parameter 1 is empty"
        exit 0
elif [! "${#timestamp}" -gt 10 ]; then
        echo "Please enter at least a valid date"
        echo "Example: 2018-08-14"
        exit 0
else
        echo "THIS IS THE VALID BLOCK"
fi
ilkkachu
  • 133,243
  • 15
  • 236
  • 397
user305422
  • 221
  • 1
  • 2
  • 3

2 Answers2

17

Well,

if [ "$1" == "" ] || [ $# -gt 1 ]; then
        echo "Parameter 1 is empty"

First, use = instead of ==. The former is standard, the latter a bashism (though I think it's from ksh, too). Second, the logic here isn't right: if $# is greater than one, then parameter 1 probably isn't empty (it might be set to the empty string, though). Perhaps you meant "$#" -lt 1, though that would also imply that "$1" = "". It should be enough to test [ "$1" = "" ], or [ "$#" -lt 1 ].

elif [! "${#timestamp}" -gt 10 ]; then

Here, the shell would try to run a command called [! (literally). You need a space in between, so [ ! "${#timestamp}" -gt 10 ]. But that's the same as [ "${#timestamp}" -le 10 ], which would also catch strings of exactly 10 characters, like 2018-08-14.

So maybe you want [ "${#timestamp}" -ne 10 ]. (!= instead of -ne would also work, even though it's a string comparison.)

if ...
    exit 0

It's customary to return with a non-zero exit code in case of an error, so use exit 1 in the error branches.


You could also use case or [[ .. ]] to pattern match the argument against the expected format, e.g.:

case "$1" in
    "")
        echo date is empty
        exit 1;;
    [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])
        echo date is ok;;
    *)
        echo "date is _not_ ok"
        exit 1;;
esac

That would also reject arguments like abcdefghij, even though it's 10 characters long.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
3

Try the below script,

Option1

timestamp="$1"

# check if command line argument is empty or not present
if [ -z $1 ]; then
        echo "Parameter 1 is empty"
        exit 0
elif [ "${#timestamp}" -lt 10 ]; then
        echo "Please enter at least a valid date"
        echo "Example: 2018-08-14"
        exit 0
else
        echo "THIS IS THE VALID BLOCK"
fi

Option2

[[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1"
Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
Stack EG
  • 1,508
  • 1
  • 11
  • 13
  • 6
    `[ -z $1 ]` would return true for an empty `$1` as you forgot to quote `$1`, so it would become `[ -z ]` which tests that the `-z` string is non-empty – Stéphane Chazelas Aug 14 '18 at 14:50
  • @StéphaneChazelas what is the diff between `""` and not using it? Using it means that there is always two chars, so not empty? – Timo Apr 13 '22 at 18:30
  • Check the [top answer](https://unix.stackexchange.com/a/462528/72988) to see the exit code used for error. Moreover, you should explain the tilde as I do not see it often in bash. – Timo Apr 13 '22 at 18:44
  • @Timo, see for instance [When is double-quoting necessary?](//unix.stackexchange.com/q/68694) – Stéphane Chazelas Apr 15 '22 at 18:01