Add shell.execute

This functions the same as shell.run, but does not tokenise the
arguments. This allows us to pass command line arguments through to
another program without having to re-quote them.

Closes #417
This commit is contained in:
SquidDev 2020-05-02 11:05:09 +01:00
parent e1663f3df0
commit fb64b6017b
4 changed files with 39 additions and 14 deletions

View File

@ -28,7 +28,7 @@ local monitor = peripheral.wrap(sName)
local previousTerm = term.redirect(monitor)
local co = coroutine.create(function()
shell.run(sProgram, table.unpack(tArgs, 3))
(shell.execute or shell.run)(sProgram, table.unpack(tArgs, 3))
end)
local function resume(...)

View File

@ -130,8 +130,25 @@ else
bgColour = colours.black
end
local function run(_sCommand, ...)
local sPath = shell.resolveProgram(_sCommand)
--- Run a program with the supplied arguments.
--
-- Unlike @{shell.run}, each argument is passed to the program verbatim. While
-- `shell.run("echo", "b c")` runs `echo` with `b` and `c`,
-- `shell.execute("echo", "b c")` runs `echo` with a single argument `b c`.
--
-- @tparam string command The program to execute.
-- @tparam string ... Arguments to this program.
-- @treturn boolean Whether the program exited successfully.
-- @usage Run `paint my-image` from within your program:
--
-- shell.execute("paint", "my-image")
function shell.execute(command, ...)
expect(1, command, "string")
for i = 1, select('#', ...) do
expect(i + 1, select(i, ...), "string")
end
local sPath = shell.resolveProgram(command)
if sPath ~= nil then
tProgramStack[#tProgramStack + 1] = sPath
if multishell then
@ -144,7 +161,7 @@ local function run(_sCommand, ...)
local sDir = fs.getDir(sPath)
local env = createShellEnv(sDir)
env.arg = { [0] = _sCommand, ... }
env.arg = { [0] = command, ... }
local result = os.run(env, sPath, ...)
tProgramStack[#tProgramStack] = nil
@ -196,11 +213,12 @@ end
-- @usage Run `paint my-image` from within your program:
--
-- shell.run("paint", "my-image")
-- @see shell.execute Run a program directly without parsing the arguments.
function shell.run(...)
local tWords = tokenise(...)
local sCommand = tWords[1]
if sCommand then
return run(sCommand, table.unpack(tWords, 2))
return shell.execute(sCommand, table.unpack(tWords, 2))
end
return false
end

View File

@ -0,0 +1 @@
_G.__arg = _ENV.arg

View File

@ -6,19 +6,25 @@ describe("The shell", function()
end)
end)
describe("shell.run", function()
it("sets the arguments", function()
local handle = fs.open("test-files/out.txt", "w")
handle.writeLine("_G.__arg = arg")
handle.close()
shell.run("/test-files/out.txt", "arg1", "arg2")
fs.delete("test-files/out.txt")
describe("shell.execute", function()
it("parses in arguments verbatim", function()
shell.execute("/test-rom/data/dump-args", "arg1", "arg 2")
local args = _G.__arg
_G.__arg = nil
expect(args):same { [0] = "/test-files/out.txt", "arg1", "arg2" }
expect(args):same { [0] = "/test-rom/data/dump-args", "arg1", "arg 2" }
end)
end)
describe("shell.run", function()
it("tokenises the arguments", function()
shell.run("/test-rom/data/dump-args", "arg1", "arg 2")
local args = _G.__arg
_G.__arg = nil
expect(args):same { [0] = "/test-rom/data/dump-args", "arg1", "arg", "2" }
end)
end)