A saída de -x vai para stderr, não stdout. Mas mesmo isso pode ser um problema - muitos scripts terão dependências funcionais do conteúdo do stderr e é meio confuso ter os fluxos de depuração e stderr misturados em alguns casos.
As versões do Bash> 4.1 oferecem uma solução diferente: a variável de ambiente BASH_XTRACEFD permite especificar um descritor de arquivo que será usado para enviar o fluxo de depuração. Pode ser um arquivo ou canal ou qualquer outra coisa que você queira.
# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19
# turn on the debug stream:
set -x
# run some commands:
cd /etc
find
echo "Well, that was fun."
# Close the output:
set +x
exec 19>&-
# See what we got:
cat /tmp/my-script.log
Com um pouco mais de mexer, você pode fazer outras coisas - como fazer um 'tee' nos fluxos stdout e / ou stdin, e intercalar aqueles com a saída de depuração, para que seu log fique mais completo. Para obter mais detalhes, consulte /programming/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself .
A grande vantagem dessa abordagem sobre as alternativas é que você não está arriscando alterações no comportamento do seu script injetando a saída de depuração no stdout ou stderr.