diff --git a/backup.py b/backup.py
index d20013a..954b923 100755
--- a/backup.py
+++ b/backup.py
@@ -10,7 +10,9 @@ import re
 import sys
 import stat
 import time
+import select
 import pathlib
+import threading
 import subprocess
 
 import typing
@@ -245,13 +247,17 @@ def main(argv: list[str]):
     args = parser.parse_args()
     config = Config(args.config)
 
+    # Run backup
     backup = Backup(config, args.dry_run)
+    captured_output: list[bytes] = []
+
     if args.dry_run:
         if args.debug:
             backup.run(sys.stdout.buffer)
         else:
             with open(os.devnull, "wb") as out:
                 backup.run(out)
+        sys.stdout.flush()
     else:
         borg = subprocess.Popen([args.borg,
                                  "create",
@@ -264,12 +270,33 @@ def main(argv: list[str]):
                                  "--paths-from-stdin",
                                  "--paths-delimiter", "\\0",
                                  "::'{hostname}-{now:%Y%m%d-%H%M%S}'"],
-                                stdin=subprocess.PIPE)
+                                stdin=subprocess.PIPE,
+                                stdout=subprocess.PIPE,
+                                stderr=subprocess.STDOUT)
         if borg.stdin is None:
             raise Exception("no pipe")
+
+        # Use a thread to capture output
+        def reader_thread(fh):
+            os.set_blocking(fh.fileno(), False)
+            while True:
+                ready = select.select([fh.fileno()], [], [])
+                if not len(ready[0]):
+                    break
+                data = fh.read(8192)
+                if not len(data):
+                    break
+                sys.stdout.buffer.write(data)
+                sys.stdout.flush()
+                captured_output.append(data)
+            fh.close()
+        reader = threading.Thread(target=reader_thread, args=(borg.stdout,))
+        reader.daemon = True
+        reader.start()
+
         try:
             # Give borg some time to start, just to clean up stdout
-            time.sleep(2)
+            time.sleep(1)
             backup.run(borg.stdin)
         except BrokenPipeError:
             sys.stderr.write(f"broken pipe\n")
@@ -279,13 +306,12 @@ def main(argv: list[str]):
             except BrokenPipeError:
                 pass
             borg.wait()
+        reader.join()
         ret = borg.returncode
         if ret < 0:
-            sys.stderr.write(f"error: process exited with signal {-ret}\n")
-            return 1
+            backup.log('E', f"borg exited with signal {-ret}")
         elif ret != 0:
-            sys.stderr.write(f"error: process exited with return code {ret}\n")
-            return ret
+            backup.log('E', f"borg exited with return code {ret}")
 
     return 0