set -u
ou
set -o nounset
Isso faria com que o shell atual tratasse as expansões de variáveis não definidas como um erro:
$ unset build
$ set -u
$ rm -rf "$build"/*
bash: build: unbound variable
set -u e set -o nounset são opções de shell POSIX .
Um valor vazio não acionará um erro.
Para isso, use
$ rm -rf "${build:?Error, variable is empty or unset}"/*
bash: build: Error, variable is empty or unset
A expansão de ${variable:?word} se expandiria para o valor de variable , a menos que esteja vazio ou não definido. Se estiver vazio ou não configurado, o word seria exibido no erro padrão e o shell trataria a expansão como um erro (o comando não seria executado e, se fosse executado em um shell não interativo, isso terminaria). Deixar o : out acionaria o erro apenas para um valor não definido, como em set -u .
${variable:?word} é uma expansão do parâmetro POSIX .
Nenhum desses causaria o encerramento de um shell interativo, a menos que set -e (ou set -o errexit ) também estivesse em vigor. ${variable:?word} faz com que os scripts saiam se a variável estiver vazia ou não definida. set -u faria com que um script fosse encerrado se usado junto com set -e .
Quanto à sua segunda pergunta. Não há como limitar o rm para não funcionar fora do diretório atual.
A implementação GNU de rm tem uma opção --one-file-system que a impede de remover recursivamente sistemas de arquivos montados, mas isso é o mais próximo que acredito ser possível sem envolver a chamada rm em uma função que realmente verifica os argumentos .
Observação: ${build} é exatamente equivalente a $build , a menos que a expansão ocorra como parte de uma sequência em que o caractere imediatamente a seguir é um caractere válido em um nome de variável, como em "${build}x" .