Repository: iterative/dvc

Issue:
When installing via deb: Failed to execute script __main__
**Setup**

DVC version: 0.22.0
Platform: Ubuntu
Method of installation: deb

**Findings**

It works if I install it via `pip`, but for CI purposes I'd prefer to be able to install it via `deb`

**Logs**

Different behaviour (cf. first line) when reinstalling it, between the first and second install.

#### First attempt

```$ sudo dvc pull
[26338] Failed to execute script __main__
[##############################] 100% Collecting information
Data 'my/dvc/tracked/file/a.json' didn't change.
Data 'my/dvc/tracked/file/b.csv' didn't change.
[26879] Failed to execute script __main__
```

#### Second attempt

```$ sudo dvc pull
[##############################] 100% Collecting information
Data 'my/dvc/tracked/file/a.json' didn't change.
Data 'my/dvc/tracked/file/b.csv' didn't change.
[27740] Failed to execute script __main__
```

#### With `--debug`

```
Data 'my/dvc/tracked/file/b.csv' didn't change.
Debug: SELECT count from state_info WHERE rowid=1
Debug: fetched: [(193,)]
Debug: UPDATE state_info SET count = 193 WHERE rowid = 1
Debug: Analytics is enabled.
Debug: Trying to spawn '['/usr/bin/dvc', 'daemon', '-q', 'analytics', '/tmp/tmpZOyC3Z']'
Debug: Spawned '['/usr/bin/dvc', 'daemon', '-q', 'analytics', '/tmp/tmpZOyC3Z']'
[27408] Failed to execute script __main__
```


Discussion:
Actually it seems that any command will end with the same last line, just tried `dvc config`
Hi @gueluelue !

Thank you for the bug report! I am indeed able to reproduce it. Looking into it right now.

Resolving patch:
diff --git a/dvc/daemon.py b/dvc/daemon.py
--- a/dvc/daemon.py
+++ b/dvc/daemon.py
@@ -1,27 +1,42 @@
 import os
 import sys
 from subprocess import Popen
+
 from dvc.logger import logger
+from dvc.utils import is_binary, fix_env
 
 
 class Daemon(object):  # pragma: no cover
     def _spawn_windows(self, cmd):
+        from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
+
         CREATE_NEW_PROCESS_GROUP = 0x00000200
         DETACHED_PROCESS = 0x00000008
         creationflags = CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
-        Popen(cmd,
-              close_fds=True,
-              shell=False,
-              creationflags=creationflags)
+
+        startupinfo = STARTUPINFO()
+        startupinfo.dwFlags |= STARTF_USESHOWWINDOW
+
+        p = Popen(cmd,
+                  env=fix_env(),
+                  close_fds=True,
+                  shell=False,
+                  creationflags=creationflags,
+                  startupinfo=startupinfo)
+
+        p.communicate()
 
     def _spawn_posix(self, cmd):
+        # NOTE: using os._exit instead of sys.exit, because dvc built
+        # with PyInstaller has trouble with SystemExit exeption and throws
+        # errors such as "[26338] Failed to execute script __main__"
         try:
             pid = os.fork()
             if pid > 0:
                 return
         except OSError as exc:
             logger.error("Failed at first fork", exc)
-            sys.exit(1)
+            os._exit(1)
 
         os.setsid()
         os.umask(0)
@@ -29,22 +44,25 @@ def _spawn_posix(self, cmd):
         try:
             pid = os.fork()
             if pid > 0:
-                sys.exit(0)
+                os._exit(0)
         except OSError as exc:
             logger.error("Failed at second fork", exc)
-            sys.exit(1)
+            os._exit(1)
 
         sys.stdin.close()
         sys.stdout.close()
         sys.stderr.close()
 
-        Popen(cmd,
-              close_fds=True,
-              shell=False)
+        p = Popen(cmd,
+                  env=fix_env(),
+                  close_fds=True,
+                  shell=False)
 
-    def __call__(self, args):
-        from dvc.utils import is_binary
+        p.communicate()
 
+        os._exit(0)
+
+    def __call__(self, args):
         cmd = [sys.executable]
         if not is_binary():
             cmd += ['-m', 'dvc']
diff --git a/dvc/utils.py b/dvc/utils.py
--- a/dvc/utils.py
+++ b/dvc/utils.py
@@ -177,7 +177,7 @@ def is_binary():
 
 # NOTE: Fix env variables modified by PyInstaller
 # http://pyinstaller.readthedocs.io/en/stable/runtime-information.html
-def fix_env(env):
+def fix_env(env=None):
     if env is None:
         env = os.environ.copy()
     else:


Test patch: