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

Custom shell on floppy disk

Started by cmdpwnd, 15 March 2014 - 02:13 AM
cmdpwnd #1
Posted 15 March 2014 - 03:13 AM
I am currently exploring the tArgs = {…} command that is used when typing parameters from the command line without entering a

program and then filling it out like a worksheet. My goal is to create a startup program on a floppy disk which will start up

a program called "cmd". the cmd program is like the shell in the computers, the difference is that it will use my own commands

which will also accept parameters. I know that you can create multiple files that use the tArgs = {…} and that then you

can do it that way, but i want my own personal shell that gives a specific line to write your command on and then it will use that

command that you just typed (parameters and all) and then run the program that you specified with the parameters. So for instance.

[disk/startup]

term.clear()

term.setCursorPos(1,1)

print("My terminal")

shell.run("disk/cmd")

[end]

 

 

[disk/cmd]

–This is were it gets sketchy

–I want to take the command I'm about to enter and execute it on another program with the parameters so please bear with me.

 

term.clear()

term.setCursorPos(1,1)

tArgs = {…}

command = tArgs[1]

parameter = tArgs[2]

print("Chad's Terminal v1.0")

print()

com()

function com()

write(">")

command = tArgs[1]

if #tArgs < 1 then



print()

print("Syntax: <command> <parameters>")

print()

print("Type: help for list of commands")

print()

rep()

else

print(command)

shell.run("disk/"..(command))

end

end

function rep()

com()

end

[end]

And then lets say the command i typed was "echo one"

i have a file called "echo" and another tArgs = {…} that looks for "one"

and then will "print(tArgs[1])" and go back to the cmd program so that i have run the command and stayed in the custom shell.
CometWolf #2
Posted 15 March 2014 - 10:05 AM
Why is every line in your post seperated by a blank one!?

You're going about this all wrong, … arguments are passed to the script by the script calling it. Since you are obviously not passing any arguments to your cmd program when you call it, there won't be any. The way the shell handles commands is using the user input read() function, then seperating each word into it's own variable, running the first variable as the program, then passing any subsequent variables to the program.
Edited on 15 March 2014 - 12:36 PM
OReezy #3
Posted 15 March 2014 - 01:24 PM
You want to run a program from your cmd program like the shell right?

To do that you would need to get an input with read () then use the string.match to separate the parts.
theoriginalbit #4
Posted 15 March 2014 - 02:35 PM
to be more precise on how it all works, here is the implementation of shell.run in ComputerCraft 1.6


local function tokenise( ... )
	local sLine = table.concat( { ... }, " " )
local tWords = {}
	local bQuoted = false
	for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
		if bQuoted then
			table.insert( tWords, match )
		else
			for m in string.gmatch( match, "[^ \t]+" ) do
				table.insert( tWords, m )
			end
		end
		bQuoted = not bQuoted
	end
	return tWords
end

-- Install shell API
function shell.run( ... )
  local tWords = tokenise( ... )
  local sCommand = tWords[1]
  if sCommand then
	return run( sCommand, unpack( tWords, 2 ) )
  end
  return false
end
Edited on 15 March 2014 - 01:36 PM
cmdpwnd #5
Posted 16 March 2014 - 05:40 AM
CometWolf, Could you give some example coding on how one might do this please?

OReezy, Could you please show how to do this?
cmdpwnd #6
Posted 16 March 2014 - 05:46 AM
I am trying to implement a small version of my own shell in computercraft which runs on a floppy.
Here is what should happen.
1.Plug in floppy
2.Floopy autoruns startup file on the floppy disk.
3.Startup file runs program "cmd"
4."cmd" uses the "write()" command to ask to type a command as you would in CraftOS.
5. For ex. user types "echo yes"
6. Cmd program takes each word from the string and separates it into different variables per word. ex. command = "echo" param1 = "yes" is the result.
7. Cmd takes the variables and plugs them into shell.run() like so shell.run("disk/"..(command),(param1))
8. This runs a program on the floppy called "echo" with the parameter "yes"
9. The called program "echo" sees parameter "yes" and runs: print(tArgs[1]) which the result is "yes"
10.Goes back to function that asked for command in cmd
Here's my code.


-- 1.At the CraftOS the startup file runs a program "cmd"
[[Program: startup]]
shell.run("cmd")
[[end of startup]]
--2.Runs program "cmd"
[[Program: cmd]]
-- Now in cmd
term.clear()
term.setCursorPos(1,1)
function prompt()
 write(">") --assuming user typed: echo yes
 tArgs = {...}

 file = tArgs[1] --will get the word "echo"
 param1 = tArgs[2] --will get the word "yes"

 if #tArgs < 1 then

  print(Syntax: <command> <parameters>)
  prompt()
 else
  print()
  shell.run("disk/"(file), (param1)) --result of running (file) with (param1) is: "yes"
  print()
  prompt()
 end
end
[[end of cmd]]
--3.Runs the program "echo" because it was the first word in our command.
[[Program: echo]]
tArgs = {...}
param = tArgs[1]
print(param) --prints "yes" which is what the "shell.run((file), (param1)) is referring to.
[[end of echo]]
And the result of this should be like so in program "cmd" as this is where the custom shell is.

>echo yes
yes
>
Any help is greatly appreciated, if you have any advice please supply code that shows how you are using it in a program.
Thank you!
Edited on 16 March 2014 - 05:01 AM
oeed #7
Posted 16 March 2014 - 07:02 AM
You'd want a read() after you write the >, take a look in the shell program in the ComputerCraft zip as to how to split the string (it's probably something using string.gmatch).

Apart from that I can't really see anything wrong with your code. Is there anything specific you're wanting help with?
theoriginalbit #8
Posted 16 March 2014 - 07:06 AM
Take a look at how ComputerCraft implements this; I've posted how they do it in your other thread for this.
Lyqyd #9
Posted 16 March 2014 - 07:27 AM
Threads merged.
cmdpwnd #10
Posted 16 March 2014 - 05:17 PM
theoriginalbit please supply code showing how this works in the ways that I want it using the format provided in my commented question restating the original question. I don't want the shell.run() file and its code I want you to actually write a program that does what I want in the given format. You referencing me doesn't help, ive already looked at it and ran it in my programs and it does nothing. Please give an example using this.
mrpoopy345 #11
Posted 16 March 2014 - 06:48 PM
A word to the wise! Look at theoriginalbit's signature!

We are not here to spoon feed you!
You want someone to make a program for you, go somewhere else.
Here in ask a pro, we are here to help you, not make something for you.
Are you getting errors? Unexpected behavior? Post some code and tell us what the problem is! Don't ask us to make something for you!

He (or she… but i think he.) Was giving you that code for a good reason!
Read his actual post.

You make the programs, not us.
cmdpwnd #12
Posted 16 March 2014 - 08:58 PM
I am asking a very simple question and getting spin off answers. so let me completely dumify the question.

1. take each word from a string and separate it them into different variables
2.take each variable and plug it into shell.run() with the first variable being the command and the rest being parameters.

showing how the shell.run() command works in ZERO help. I know how it works.
I want to ask the user to type something and from that "fill out" the shell.run() command
that simple
Lyqyd #13
Posted 16 March 2014 - 09:06 PM
You don't have to split it out. You could just do shell.run(read()) and it would run the command just like if you entered it in the normal shell.
cmdpwnd #14
Posted 16 March 2014 - 09:34 PM
so i would be able to do this?

write(">")
command = read()
shell.run(read())
Dog #15
Posted 16 March 2014 - 09:45 PM
With your code, you would create two read events (it would ask for input twice - once to set command and again to execute the shell.run). What you're looking for is either of the following:


write(">")
shell.run(read())

or


write(">")
command  = read()
shell.run(command)
Edited on 16 March 2014 - 08:58 PM
theoriginalbit #16
Posted 17 March 2014 - 02:53 AM
theoriginalbit please supply code showing how this works in the ways that I want it using the format provided in my commented question restating the original question. I don't want the shell.run() file and its code I want you to actually write a program that does what I want in the given format. You referencing me doesn't help, ive already looked at it and ran it in my programs and it does nothing. Please give an example using this.
well based on the question you'd asked at the time you were only wanting to split the words into commands and arguments, there was no mention of passing these to shell.run, as such the code I posted was a perfect example of how to do it, actually it was the answer to your question. If you'd bothered to read the code you'd have seen that shell.run called a function called tokenise which splits a string into words but not splitting them when surrounded in quotes. So program foo bar would be "program", "foo", and "bar"; whereas program "foo bar" would be "program" and "foo bar".