Zendo

TIL: Redirect Bash `set -x` to file

Sometimes you will need to debug commands that are being called as sub-commands to another process. Case-in-point are external git diff helpers for special files, and in my case the rails encrypted credentials file.

I wanted to intercept calls to this command and write out the arguments that this script was being called with to a log file.

Here's what I did:

  1. Create the diff script and save to ~/rails_differ

    #!/bin/bash
    
    exec 10>/home/chris/rails_differ.log
    BASH_XTRACEFD=10
    set -x
    
    bundle exec rails credentials:diff "$@"
    
    • The key here is that you can set the BASH_XTRACEFD=19, the file descriptor 19 is arbitrary, as long as you do not use the special FDs 0 (STDIN), 1 (STDOUT),2 (STDERR), it should be fine.
    • 19>/home/chris/rails_differ.log opens the file descriptor and points it to the log
    • set -x enables command tracing
  2. Update .git/config in the repository from

    [diff "rails_credentials"]
    textconv = bin/rails credentials:diff
    

    to

    [diff "rails_credentials"]
    textconv = /home/chris/rails_differ
    
  3. And of course make sure your .gitattributes contains

    config/credentials/*.yml.enc diff=rails_credentials
    config/credentials.yml.enc diff=rails_credentials
    
  4. Now when I run

    git diff -- config/credentials/test.yml.enc
    
  5. Then by cat ~/rails_differ.log I can see

    + bundle exec rails credentials:diff config/credentials/test.yml.enc
    

#til