Implement the Linux env utility in Go. The env utility examines the environment
ID: 3743699 • Letter: I
Question
Implement the Linux env utility in Go. The env utility examines the environment and modifies it to ex- ecute another command. When called without arguments, the env command writes the current environment to standard output. The optional utility argument specifies the command to be exe- cuted under the modified environment. The optional -i argument means that env should ignore the environment inherited from the shell when executing utility. Without the -i option, env uses the [name=value] arguments to modify rather than replace the cur- rent environment to execute utility. The env command does not modify the environment of the shell which executes it.
Explanation / Answer
/*****************************************************
Compile it using go build env.go
And run ./env
Then run ./env ABC=DEF env
You can see it work
Do give a feedback because it would really be heloful
**************************************************/
/************env.go********************/
package main
//Importing packages
import (
"bytes"
"os"
"os/exec"
"strings"
"fmt"
)
func main() {
// Fetch all command line arguments except the program name
args := os.Args[1:]
// Iterate over the command line arguments
for i := 0; i < len(args); i++ {
if args[i] == "-i" {
//Clear the environment variables if -i flag is found
os.Clearenv()
} else {
//If not a flag then get a key=value pair and split it around =
pair := strings.Split(args[i], "=")
// If there is only one value, it means we have a command
// If not then set the environment variable
if(len(pair) == 2) {
os.Setenv(pair[0], pair[1])
} else {
// Else run the command with the rest of the array as arguments
Excecute(args[i], args[i + 1:])
break;
}
}
}
if len(args) == 0 {
// If there were no arguments then print the environment variables
Printenv()
}
}
func Printenv() {
// Get the list of environment variables and iterate over it
// Split it around - and print it
for _, e := range os.Environ() {
pair := strings.Split(e, "-")
fmt.Println(pair[0])
}
}
func Excecute(s string, args []string) {
// Set the command and the argument list
cmd := exec.Command(s, args...)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
//Sets the STDOUT and STDERR buffers and runs the command
cmd.Run()
// If the STDOUT buffer is not empty, print everything
if s := out.String(); len(s) != 0 {
fmt.Printf("%v", s)
}
// If the STDERR buffer is not empty, print everything
if s := stderr.String(); len(s) != 0 {
fmt.Printf("%v", s)
}
}