Coder Social home page Coder Social logo

Comments (12)

shumin1027 avatar shumin1027 commented on July 22, 2024 2

This is how I solve this problem:

package shell

import (
	"bytes"
	"github.com/bitfield/script"
	"os/exec"
)

type PipeWrap struct {
	*script.Pipe
}

func (p *PipeWrap) ToPipe(s string) *script.Pipe {
	return p.Pipe
}

func (p *PipeWrap) Exec(s string) *script.Pipe {
	if p == nil || p.Error() != nil {
		return p.Pipe
	}
	q := NewPipeWrap()
	//args := strings.Fields(s)
	cmd := exec.Command("bash", "-c", s)
	cmd.Stdin = p.Reader
	output, err := cmd.CombinedOutput()
	if err != nil {
		q.SetError(err)
	}
	return q.WithReader(bytes.NewReader(output))
}
func NewPipeWrap() *PipeWrap {
	PipeWrap := new(PipeWrap)
	PipeWrap.Pipe = script.NewPipe()
	return PipeWrap
}

func Exec(s string) *script.Pipe {
	return NewPipeWrap().Exec(s)
}

from script.

posener avatar posener commented on July 22, 2024 1

The right solution for this problem is to change the API of Exec to a (string, ...string), exactly as the exec.Command API is, and pass it as is to the exec.Command call.

from script.

bitfield avatar bitfield commented on July 22, 2024 1

That's actually a little bit of a pain, which is one reason why we wrap exec.Command to be able to pass it a single string.

from script.

bitfield avatar bitfield commented on July 22, 2024

Thanks for the report @shumin1027! PR welcome, from anyone who wants to tackle this.

from script.

posener avatar posener commented on July 22, 2024

That's actually a little bit of a pain, which is one reason why we wrap exec.Command to be able to pass it a single string.

I'm not sure I fully understand what is the pain point. Having the input as a single string?

from script.

bitfield avatar bitfield commented on July 22, 2024

Yes, exec.Command takes a string and a slice of strings as the command line. In shell scripts we can simply write this as one string, so script replicates this.

from script.

posener avatar posener commented on July 22, 2024

from script.

bitfield avatar bitfield commented on July 22, 2024

Unless you quote it, of course, which is what this issue is really about.

from script.

posener avatar posener commented on July 22, 2024

Quoting does not help: The input string is passed to strings.Field, which is passed to the exec.Command in the next line.

Unfortunately, the strings.Fields does not group into a single field quoted words:

fmt.Println(strings.Join(strings.Fields(`a b "c d" e`), ", "))
// Output: a, b, "c, d", e

Notice that in this example, "c is one string returned from strings.Fields and d" is another, while for the command.Exec you would want c d as a single string.

from script.

NightMachinery avatar NightMachinery commented on July 22, 2024

@shumin1027 commented on Oct 10, 2019, 4:35 AM GMT+3:30:

This is how I solve this problem:

package shell

import (
	"bytes"
	"github.com/bitfield/script"
	"os/exec"
)

type PipeWrap struct {
	*script.Pipe
}

func (p *PipeWrap) ToPipe(s string) *script.Pipe {
	return p.Pipe
}

func (p *PipeWrap) Exec(s string) *script.Pipe {
	if p == nil || p.Error() != nil {
		return p.Pipe
	}
	q := NewPipeWrap()
	//args := strings.Fields(s)
	cmd := exec.Command("bash", "-c", s)
	cmd.Stdin = p.Reader
	output, err := cmd.CombinedOutput()
	if err != nil {
		q.SetError(err)
	}
	return q.WithReader(bytes.NewReader(output))
}
func NewPipeWrap() *PipeWrap {
	PipeWrap := new(PipeWrap)
	PipeWrap.Pipe = script.NewPipe()
	return PipeWrap
}

func Exec(s string) *script.Pipe {
	return NewPipeWrap().Exec(s)
}

I'm new to go, but I guess there is no way to make that custom Exec method work in the middle of a pipe? (Because all functions in the library return script.Pipe, which we can't add an extension method to.)

from script.

shumin1027 avatar shumin1027 commented on July 22, 2024

@shumin1027 commented on Oct 10, 2019, 4:35 AM GMT+3:30:

This is how I solve this problem:

package shell

import (
	"bytes"
	"github.com/bitfield/script"
	"os/exec"
)

type PipeWrap struct {
	*script.Pipe
}

func (p *PipeWrap) ToPipe(s string) *script.Pipe {
	return p.Pipe
}

func (p *PipeWrap) Exec(s string) *script.Pipe {
	if p == nil || p.Error() != nil {
		return p.Pipe
	}
	q := NewPipeWrap()
	//args := strings.Fields(s)
	cmd := exec.Command("bash", "-c", s)
	cmd.Stdin = p.Reader
	output, err := cmd.CombinedOutput()
	if err != nil {
		q.SetError(err)
	}
	return q.WithReader(bytes.NewReader(output))
}
func NewPipeWrap() *PipeWrap {
	PipeWrap := new(PipeWrap)
	PipeWrap.Pipe = script.NewPipe()
	return PipeWrap
}

func Exec(s string) *script.Pipe {
	return NewPipeWrap().Exec(s)
}

I'm new to go, but I guess there is no way to make that custom Exec method work in the middle of a pipe? (Because all functions in the library return script.Pipe, which we can't add an extension method to.)

This issue seems to have been fixed Fix Exec to handle quotes #42
example : https://github.com/bitfield/script/blob/master/examples/execute/main.go

from script.

bitfield avatar bitfield commented on July 22, 2024

That would explain why it's closed...

from script.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.