github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/pkg/eval/builtin_fn_cmd.go (about)

     1  package eval
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  )
     8  
     9  // Command and process control.
    10  
    11  // TODO(xiaq): Document "fg".
    12  
    13  func init() {
    14  	addBuiltinFns(map[string]interface{}{
    15  		// Command resolution
    16  		"external":        external,
    17  		"has-external":    hasExternal,
    18  		"search-external": searchExternal,
    19  
    20  		// Process control
    21  		"fg":   fg,
    22  		"exec": execFn,
    23  		"exit": exit,
    24  	})
    25  }
    26  
    27  //elvdoc:fn external
    28  //
    29  // ```elvish
    30  // external $program
    31  // ```
    32  //
    33  // Construct a callable value for the external program `$program`. Example:
    34  //
    35  // ```elvish-transcript
    36  // ~> x = (external man)
    37  // ~> $x ls # opens the manpage for ls
    38  // ```
    39  //
    40  // @cf has-external search-external
    41  
    42  func external(cmd string) Callable {
    43  	return NewExternalCmd(cmd)
    44  }
    45  
    46  //elvdoc:fn has-external
    47  //
    48  // ```elvish
    49  // has-external $command
    50  // ```
    51  //
    52  // Test whether `$command` names a valid external command. Examples (your output
    53  // might differ):
    54  //
    55  // ```elvish-transcript
    56  // ~> has-external cat
    57  // ▶ $true
    58  // ~> has-external lalala
    59  // ▶ $false
    60  // ```
    61  //
    62  // @cf external search-external
    63  
    64  func hasExternal(cmd string) bool {
    65  	_, err := exec.LookPath(cmd)
    66  	return err == nil
    67  }
    68  
    69  //elvdoc:fn search-external
    70  //
    71  // ```elvish
    72  // search-external $command
    73  // ```
    74  //
    75  // Output the full path of the external `$command`. Throws an exception when not
    76  // found. Example (your output might vary):
    77  //
    78  // ```elvish-transcript
    79  // ~> search-external cat
    80  // ▶ /bin/cat
    81  // ```
    82  //
    83  // @cf external has-external
    84  
    85  func searchExternal(cmd string) (string, error) {
    86  	return exec.LookPath(cmd)
    87  }
    88  
    89  //elvdoc:fn exit
    90  //
    91  // ```elvish
    92  // exit $status?
    93  // ```
    94  //
    95  // Exit the Elvish process with `$status` (defaulting to 0).
    96  
    97  func exit(fm *Frame, codes ...int) error {
    98  	code := 0
    99  	switch len(codes) {
   100  	case 0:
   101  	case 1:
   102  		code = codes[0]
   103  	default:
   104  		return ErrArgs
   105  	}
   106  
   107  	preExit(fm)
   108  	os.Exit(code)
   109  	// Does not return
   110  	panic("os.Exit returned")
   111  }
   112  
   113  func preExit(fm *Frame) {
   114  	daemon := fm.Evaler.DaemonClient()
   115  	if daemon != nil {
   116  		err := daemon.Close()
   117  		if err != nil {
   118  			fmt.Fprintln(os.Stderr, err)
   119  		}
   120  	}
   121  }