Приложение My Go выводит некоторые количества текстовых данных, и мне нужно передать его какой-либо внешней команде (например, less
). Я не нашел способа передать эти данные в процесс syscall.Exec
.Труба к процессу exec'ed
В качестве обходного пути я пишу, что текстовые данные во временный файл, а затем использовать этот файл в качестве аргумента less
:
package main
import (
"io/ioutil"
"log"
"os"
"os/exec"
"syscall"
)
func main() {
content := []byte("temporary file's content")
tmpfile, err := ioutil.TempFile("", "example")
if err != nil {
log.Fatal(err)
}
defer os.Remove(tmpfile.Name()) // Never going to happen!
if _, err := tmpfile.Write(content); err != nil {
log.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
log.Fatal(err)
}
binary, err := exec.LookPath("less")
if err != nil {
log.Fatal(err)
}
args := []string{"less", tmpfile.Name()}
if err := syscall.Exec(binary, args, os.Environ()); err != nil {
log.Fatal(err)
}
}
Он работает, но оставляет временный файл в файловой системе, так как syscall.Exec
заменяет текущий процесс Go с другим (less
) один и отложенный os.Remove
не запускается. Такое поведение нежелательно.
Есть ли способ передать некоторые данные во внешний процесс, не оставляя никаких артефактов?
Спасибо, я знаю о 'os/exec' * et al *, но это не решит мою проблему вообще. Я хочу передать данные в пейджеровую среду ('less'), а не обрабатывать некоторые текстовые утилиты и обрабатывать выходные данные. –
@PetrShevtsov: Я неправильно понял, потому что вы не можете напрямую подключиться к процессу, который вы собираетесь выполнять. Труба блокируется и данные должны быть где-то буферизованы. Это не проблема Go, потому что вы не можете этого делать в целом. Если вы находитесь в системе posix (которую я предполагаю с вызовами syscall.Exec и 'less'), вы можете просто удалить файл tmp. – JimB
спасибо, это работает! Но могу ли я избавиться от временного файла и написать непосредственно на 'syscall.Stdin'? –