O ponto e vírgula é obrigatório, porque sem uma indicação de onde esse contexto termina (através de um ponto e vírgula, nova linha, etc), if não pode saber onde a condição termina, e o bloco condicional começa. Comparar:
$ if echo then foo then; then :; fi
then foo then
$ if echo then; then :; fi
then
-d é um teste para verificar se o próximo argumento é um diretório. De help test (porque test é equivalente a [ ):
-d FILE True if file is a directory.
Por exemplo:
$ mkdir foo
$ if [ -d foo ]; then
> echo foo is a dir
> fi
foo is a dir
$1 é o primeiro argumento passado para o seu programa. Por exemplo:
$ cat > script << 'EOF'
> #!/bin/sh
> echo "$1"
> EOF
$ chmod +x script
$ ./script foo
foo
Como um aparte, você deve citar $1 aqui, porque senão ele pode se expandir em múltiplos argumentos, resultando em um erro de sintaxe de [ :
$ dir="foo bar"
$ [ -d $dir ]
sh: 2: [: foo: unexpected operator
$ [ -d "$dir" ]
$