Example #1
0
    def Eval(self, node):
        # type: (command_t) -> None

        UP_node = node
        with tagswitch(node) as case:
            if case(command_e.Simple):
                node = cast(command__Simple, UP_node)

                # Need splitter for this.
                if 0:
                    cmd_val = self.word_ev.EvalWordSequence2(node.words,
                                                             allow_assign=True)
                    for arg in cmd_val.argv:
                        log('arg %s', arg)
                for w in node.words:
                    val = self.word_ev.EvalWordToString(w)
                    # TODO: how to print repr() in C++?
                    log('arg %d', val.tag_())

            elif case(command_e.DParen):
                node = cast(command__DParen, UP_node)

                a = self.arith_ev.Eval(node.child)
                # TODO: how to print repr() in C++?
                log('arith val %d', a.tag_())

            else:
                log('Unhandled node %s', NewStr(command_str(node.tag_())))
Example #2
0
    def RunCommandSub(self, node):
        # type: (command_t) -> str

        # Hack for weird $(<file) construct
        if node.tag_() == command_e.Simple:
            simple = cast(command__Simple, node)
            # Detect '< file'
            if (len(simple.words) == 0 and len(simple.redirects) == 1
                    and simple.redirects[0].op.id == Id.Redir_Less):
                # change it to __cat < file
                # note: cmd_eval.py _Dispatch works around lack of spid
                tok = Token(Id.Lit_Chars, runtime.NO_SPID, '__cat')
                cat_word = compound_word([tok])
                # MUTATE the command.Simple node.  This will only be done the first
                # time in the parent process.
                simple.words.append(cat_word)

        p = self._MakeProcess(node,
                              inherit_errexit=self.exec_opts.inherit_errexit())

        r, w = posix.pipe()
        p.AddStateChange(process.StdoutToPipe(r, w))
        _ = p.Start()
        #log('Command sub started %d', pid)

        chunks = []  # type: List[str]
        posix.close(w)  # not going to write
        while True:
            byte_str = posix.read(r, 4096)
            if len(byte_str) == 0:
                break
            chunks.append(byte_str)
        posix.close(r)

        status = p.Wait(self.waiter)

        # OSH has the concept of aborting in the middle of a WORD.  We're not
        # waiting until the command is over!
        if self.exec_opts.more_errexit():
            if self.exec_opts.errexit() and status != 0:
                raise error.ErrExit('Command sub exited with status %d (%r)',
                                    status, NewStr(command_str(node.tag_())))
        else:
            # Set a flag so we check errexit at the same time as bash.  Example:
            #
            # a=$(false)
            # echo foo  # no matter what comes here, the flag is reset
            #
            # Set ONLY until this command node has finished executing.

            # HACK: move this
            self.cmd_ev.check_command_sub_status = True
            self.mem.SetLastStatus(status)

        # Runtime errors test case: # $("echo foo > $@")
        # Why rstrip()?
        # https://unix.stackexchange.com/questions/17747/why-does-shell-command-substitution-gobble-up-a-trailing-newline-char
        return ''.join(chunks).rstrip('\n')
Example #3
0
def CommandType(cmd):
    # type: (command_t) -> str
    """For displaying commands in the UI."""

    # Displays 'value.MaybeStrArray' for now, maybe change it.
    return NewStr(command_str(cmd.tag_()))