Eu fiz um strace em um scp de um arquivo. Parece que scp não usa um nome de arquivo temporário como wget , na verdade, verifica a existência do arquivo de destino e o abre com O_WRONLY|O_CREAT . O arquivo de destino deve existir se scp for muito longe para realmente ter dados para gravar.
Não há como haver uma "corrida" entre a existência do arquivo de destino e a verificação de sua existência. O shell precisará obter SIGCHLD de scp exiting para obter o status de saída e decidir que o status é diferente de zero. Tenho certeza que o kernel cuidaria do nome do arquivo existente quando o processo scp sair. A criação de arquivos é supostamente atômica. Não se preocupe em adicionar um sleep , não vai ajudar.
A única maneira de seu código de exemplo chegar ao teste de existência do arquivo de destino ( [ -f $scptarget ] ) é se scp sair com o status 0 (zero). É certamente possível que o arquivo exista, mas tenha uma condição de erro. Você verifica o arquivo $scptarget para correção e integridade quando ocorre um erro? Você pode acabar com um arquivo parcial ou mutilado.
Eu acho que para descobrir o que está acontecendo, você teria que usar 2 if constructos, um para o status de saída de scp e o segundo para a existência do arquivo de destino. Certifique-se de que as mensagens sejam diferentes e registre $? , o status de saída do processo scp .