# Buggy code
def run(self, dry=False):
    if self.locked:
        msg = "Verifying outputs in locked stage '{}'"
        self.project.logger.info(msg.format(self.relpath))
        if not dry:
            self.check_missing_outputs()
    elif self.is_import:
        msg = "Importing '{}' -> '{}'"
        self.project.logger.info(msg.format(self.deps[0].path, self.outs[0].path))

        if not dry:
            self.deps[0].download(self.outs[0].path_info)
    elif self.is_data_source:
        msg = "Verifying data sources in '{}'".format(self.relpath)
        self.project.logger.info(msg)
        if not dry:
            self.check_missing_outputs()
    else:
        msg = "Running command:\n\t{}".format(self.cmd)
        self.project.logger.info(msg)

        if not dry:
            self._check_missing_deps()
            p = subprocess.Popen(
                self.cmd,
                cwd=self.cwd,
                shell=True,
                env=fix_env(os.environ),
                executable=os.getenv("SHELL"),
            )
            p.communicate()
            if p.returncode != 0:
                raise StageCmdFailedError(self)

    if not dry:
        self.save()


# Traceback (StageCmdFailedError)
$ dvc run -v -d data/Posts.xml.tgz -o data/Posts.xml tar zxf data/Posts.xml.tgz -C data/
Debug: updater is not old enough to check for updates
Debug: PRAGMA user_version;
Debug: fetched: [(2,)]
Debug: CREATE TABLE IF NOT EXISTS state (inode INTEGER PRIMARY KEY, mtime TEXT NOT NULL, md5 TEXT NOT NULL, timestamp TEXT NOT NULL)
Debug: CREATE TABLE IF NOT EXISTS state_info (count INTEGER)
Debug: CREATE TABLE IF NOT EXISTS link_state (path TEXT PRIMARY KEY, inode INTEGER NOT NULL, mtime TEXT NOT NULL)
Debug: INSERT OR IGNORE INTO state_info (count) SELECT 0 WHERE NOT EXISTS (SELECT * FROM state_info)
Debug: PRAGMA user_version = 2;
Running command:
tar zxf data/Posts.xml.tgz -C data/
/c: /c: Is a directory
Debug: SELECT count from state_info WHERE rowid=1
Debug: fetched: [(1,)]
Debug: UPDATE state_info SET count = 1 WHERE rowid = 1
Error: Traceback (most recent call last):
File "dvc\command\run.py", line 18, in run
File "dvc\project.py", line 265, in run
File "dvc\stage.py", line 435, in run
StageCmdFailedError: Stage 'Posts.xml.dvc' cmd tar zxf data/Posts.xml.tgz -C data/ failed

Error: Failed to run command: Stage 'Posts.xml.dvc' cmd tar zxf data/Posts.xml.tgz -C data/ failed

# Fixed code
def run(self, dry=False):
    if self.locked:
        msg = "Verifying outputs in locked stage '{}'"
        self.project.logger.info(msg.format(self.relpath))
        if not dry:
            self.check_missing_outputs()
    elif self.is_import:
        msg = "Importing '{}' -> '{}'"
        self.project.logger.info(msg.format(self.deps[0].path, self.outs[0].path))

        if not dry:
            self.deps[0].download(self.outs[0].path_info)
    elif self.is_data_source:
        msg = "Verifying data sources in '{}'".format(self.relpath)
        self.project.logger.info(msg)
        if not dry:
            self.check_missing_outputs()
    else:
        msg = "Running command:\n\t{}".format(self.cmd)
        self.project.logger.info(msg)

        if not dry:
            self._check_missing_deps()
            executable = os.getenv("SHELL") if os.name != "nt" else None
            p = subprocess.Popen(
                self.cmd,
                cwd=self.cwd,
                shell=True,
                env=fix_env(os.environ),
                executable=executable,
            )
            p.communicate()
            if p.returncode != 0:
                raise StageCmdFailedError(self)

    if not dry:
        self.save()