compile_effect_unix_test.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //go:build !windows && !plan9
  2. package eval_test
  3. import (
  4. "os"
  5. "strings"
  6. "testing"
  7. "src.elv.sh/pkg/eval/errs"
  8. . "src.elv.sh/pkg/eval/evaltest"
  9. "src.elv.sh/pkg/testutil"
  10. )
  11. func TestPipeline_ReaderGone_Unix(t *testing.T) {
  12. Test(t,
  13. // External commands terminated by SIGPIPE due to reader exiting early
  14. // raise ReaderGone, which is then suppressed.
  15. That("yes | true").DoesNothing(),
  16. That(
  17. "var reached = $false",
  18. "{ yes; reached = $true } | true",
  19. "put $reached",
  20. ).Puts(false),
  21. )
  22. }
  23. func TestCommand_External(t *testing.T) {
  24. d := testutil.InTempDir(t)
  25. mustWriteScript("foo", "#!/bin/sh", "echo foo")
  26. mustWriteScript("lorem/ipsum", "#!/bin/sh", "echo lorem ipsum")
  27. testutil.Setenv(t, "PATH", d+"/bin")
  28. mustWriteScript("bin/hello", "#!/bin/sh", "echo hello")
  29. Test(t,
  30. // External commands, searched and relative
  31. That("hello").Prints("hello\n"),
  32. That("./foo").Prints("foo\n"),
  33. That("lorem/ipsum").Prints("lorem ipsum\n"),
  34. // Using the explicit e: namespace.
  35. That("e:hello").Prints("hello\n"),
  36. That("e:./foo").Prints("foo\n"),
  37. // Relative external commands may be a dynamic string.
  38. That("var x = ipsum", "lorem/$x").Prints("lorem ipsum\n"),
  39. // Searched external commands may not be a dynamic string.
  40. That("var x = hello; $x").Throws(
  41. errs.BadValue{What: "command",
  42. Valid: "callable or string containing slash", Actual: "hello"},
  43. "$x"),
  44. // Using new FD as destination in external commands.
  45. // Regression test against b.elv.sh/788.
  46. That("./foo 5</dev/null").Prints("foo\n"),
  47. // Using pragma to allow or disallow implicit searched commands
  48. That("pragma unknown-command = disallow", "hello").DoesNotCompile(),
  49. That("pragma unknown-command = external", "hello").Prints("hello\n"),
  50. // Pragma applies to subscope
  51. That("pragma unknown-command = disallow", "{ hello }").DoesNotCompile(),
  52. // Explicit uses with e: is always allowed
  53. That("pragma unknown-command = disallow", "e:hello").Prints("hello\n"),
  54. // Relative external commands are always allowed
  55. That("pragma unknown-command = disallow", "./foo").Prints("foo\n"),
  56. That("pragma unknown-command = disallow", "var x = ./foo", "$x").Prints("foo\n"),
  57. )
  58. }
  59. func mustWriteScript(name string, lines ...string) {
  60. testutil.MustWriteFile(name, strings.Join(lines, "\n"))
  61. testutil.Must(os.Chmod(name, 0700))
  62. }