Não sei bem por que o comando travaria, mas você não precisa executar todo o pipeline no servidor. É o suficiente para fazer o ls lá:
backup_folder=$( ssh -i keyfile "$server" "ls -t '$dir'" | head -n 1 )
Observe que isso cita o valor $dir no lado remoto (ele ainda será expandido localmente). O head será executado localmente.
Isso também vem com as advertências mencionadas nas respostas para " Por que * not * pars 'ls'? ".