This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
CodingWithClass's profile picture

Looking for a CLI shell

Started by CodingWithClass, 24 May 2014 - 12:29 AM
CodingWithClass #1
Posted 24 May 2014 - 02:29 AM
I'm making an OS which needs both a graphical shell and a command line shell. I'm going to handle graphical, but does anyone know of a good simple shell? I seem to be terrible at this stuff…
(
Spoiler

term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
shellVars = {}
shellVars.PS1 = "$ "
shellVars.PS1Color = {
  ['bg'] = colors.black,
  ['fg'] = colors.yellow,
}
local accepting = true
while accepting do
  term.setBackgroundColor(shellVars.PS1Color.bg)
  term.setTextColor(shellVars.PS1Color.fg)
  write(shellVars.PS1)
  term.setBackgroundColor(colors.black)
  term.setTextColor(colors.white)
  local inputCMD = read()
  if inputCMD == "exit" then
    accepting = false
  elseif inputCMD == "help" then
    print(" ")
    print("CWCOS sh version 1")
    print("Built-in commands:")
    print("exit - exits")
    print("help - shows this help")
  else
   local split = string.gmatch(inputCMD, "%S+")
   local cmd = split[0]
   print("Split:")
   print(textutils.serialize(split))
   print("CMD:")
   print(cmd)
   sleep(5)
   table.remove(split, 0)
   if split[0] then
      os.run({}, cmd, split)
    else
      os.run({}, cmd)
    end
  end
end
) See if you can fix that :P/>
Lyqyd #2
Posted 24 May 2014 - 03:20 AM
Moved to Ask a Pro.
Link149 #3
Posted 24 May 2014 - 03:50 AM
Shells/Command lines are pretty easy to write, depending of what you want it to do.
Here's a small Lua shell which can interpret some Lua code entered by a user. Notice how
it looks like CraftOS' Interactive Lua prompt.





-- Some Lua shell

local bRunning = true
local tHistory = {}
local tEnv = {
	["exit"] = function() bRunning = false end
}


local function main()
  --# The Main loop, should repeat until the user calls
  --# 'exit()' from within the loop.
  while bRunning == true do
  
	--# Let's print a small 'cursor', just to let the user
	--# know it's his turn to talk.
	write("> ")


	--# Read user input and store it in an history table.
	--# The history table is not necessary but it allows you to
	--# to keep track of the previous user input strings and repeat
	--# a sentence by pressing the 'up' key on the keyboard.
	local sInput = read(nil, tHistory)
	table.add(tHistory, sInput)
  
	--# Dynamically create a function out of the user's input.
	local fFunction, sError = loadstring(sInput, "chunkname")
  
	--# Check if fFunction exists. If it does then the user input
	--# contained syntactically correct Lua code.
	if fFunction then
	  
	   --# Now this one is probably my favorite part. :)/>/>/>
	   --# It allows you to specify the global variables available from your shell.
	   --# Which means anything that is not in tEnv "does not
	   --# exist" within your Lua shell.
	   setfenv(fFunction, tEnv)
	  
	   --# Call the function in protected mode (we made sure there
	   --# is no syntax error, but what about runtime errors such
	   --# as recursions ?) and capture every returned values.
	   local tResults = { pcall(function() return fFunction() end) }
	  
	   --# If pcall succeeded then tResults[1] is true, otherwise,
	   --# in case of runtime error, its nil. Let's check if it is any
	   --# value other than nil.
	   if tResults[1] then
		
		 --# If the function succeeded,
		 --# lets print the returned values.
		 for i, v in pairs({ unpack(tResults, 2) }) do
		   print(v)
		 end
	   else
		
		 --# If there was a runtime error, then tResults[2] is the
		 --# error message. Let's print it.
		 printError(tResults[2])
	   end
	else
	  
	   --# Otherwise then print the syntax error...
	   printError(sError)
	end
  end
end

Hope this helped. If you have trouble with something, maybe I can clarify it.
Edited on 24 May 2014 - 01:52 AM
InputUsername #4
Posted 24 May 2014 - 11:23 AM
Shells/Command lines are pretty easy to write, depending of what you want it to do.
Here's a small Lua shell which can interpret some Lua code entered by a user. Notice how
it looks like CraftOS' Interactive Lua prompt.

Spoiler


-- Some Lua shell

local bRunning = true
local tHistory = {}
local tEnv = {
	["exit"] = function() bRunning = false end
}


local function main()
  --# The Main loop, should repeat until the user calls
  --# 'exit()' from within the loop.
  while bRunning == true do
  
	--# Let's print a small 'cursor', just to let the user
	--# know it's his turn to talk.
	write("> ")


	--# Read user input and store it in an history table.
	--# The history table is not necessary but it allows you to
	--# to keep track of the previous user input strings and repeat
	--# a sentence by pressing the 'up' key on the keyboard.
	local sInput = read(nil, tHistory)
	table.add(tHistory, sInput)
  
	--# Dynamically create a function out of the user's input.
	local fFunction, sError = loadstring(sInput, "chunkname")
  
	--# Check if fFunction exists. If it does then the user input
	--# contained syntactically correct Lua code.
	if fFunction then
	  
	   --# Now this one is probably my favorite part. :)/>/>/>/>/>/>
	   --# It allows you to specify the global variables available from your shell.
	   --# Which means anything that is not in tEnv "does not
	   --# exist" within your Lua shell.
	   setfenv(fFunction, tEnv)
	  
	   --# Call the function in protected mode (we made sure there
	   --# is no syntax error, but what about runtime errors such
	   --# as recursions ?) and capture every returned values.
	   local tResults = { pcall(function() return fFunction() end) }
	  
	   --# If pcall succeeded then tResults[1] is true, otherwise,
	   --# in case of runtime error, its nil. Let's check if it is any
	   --# value other than nil.
	   if tResults[1] then
		
		 --# If the function succeeded,
		 --# lets print the returned values.
		 for i, v in pairs({ unpack(tResults, 2) }) do
		   print(v)
		 end
	   else
		
		 --# If there was a runtime error, then tResults[2] is the
		 --# error message. Let's print it.
		 printError(tResults[2])
	   end
	else
	  
	   --# Otherwise then print the syntax error...
	   printError(sError)
	end
  end
end

Hope this helped. If you have trouble with something, maybe I can clarify it.
Isn't this basically the built-in 'lua' program with comments on how it works?
Never mind, I should really learn to think before I speak.

Anyway, I don't really understand why you wouldn't just use the built-in 'shell' program. That sounds exactly like what you need.
You could even try copying the shell's source code and then editing it to suit your needs.
Edited on 24 May 2014 - 09:24 AM
CodingWithClass #5
Posted 24 May 2014 - 04:41 PM
You could even try copying the shell's source code and then editing it to suit your needs.
Thanks, great idea and just what I needed.