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

[SOLVED] file:write how to make it write program code?

Started by BigSHinyToys, 22 March 2012 - 06:14 AM
BigSHinyToys #1
Posted 22 March 2012 - 07:14 AM
so this code should make a file called startup and then reboot the computer
It does this of if i use file:write("hello") it makes file and places the word hello in it then and crashed because startup is not a proper program. but no when i use file:write("print("hello")")
local file = io.open( "startup", "w" )
print(file)
file:write("print("hello")")
file:close()
os.reboot()

any help on how to make a program make a file that contained a program that was in the main program will help alot.

reasons for why im looking for this info

I have made a node program I would like it to on first run make a startup file and the reboot the system. so the startup file will run node and if it crashes startup will run node again and log the error. also it would be able to update its self from me sending it a command and new code. but ot do all that i need to know whats up with this code

SOLUTION use a multi line quote.

example The bellow code is the real startup file from "node ver 5" all rights NOT reserved. do with it what ever you would like.

if fs.exists("startup") == false then
sStartup = [[
-- This is the startup program that is installed by Node.
startVer = 0.1
print("Initializing node")
if fs.exists("install") then
print("installed new ver of Node")
fs.delete("node")
fs.move("install","node")
end
while true do
sleep(2)
local value1, value2 = shell.run("node")
if value1 == nil then
print("nil")
else
print(value1)
end
if value2 == nil then
print("nil")
else
print(value2)
end
if value1 then break end
end
-- end of
]]
print("Installing startup")
local file = io.open( "startup", "w" )
file:write(sStartup)
file:close()
print("Rebooting in 3 seconds")
sleep(3)
os.reboot()
else
sStartup = nil
end
Luanub #2
Posted 22 March 2012 - 07:27 AM
try doing file:write("shell.run("program_name")")

Not at home so I cant test it but it should work.
Xtansia #3
Posted 22 March 2012 - 07:33 AM
You need to escape the " that are in the string,
To escape the " you put a backslash in front of it ( " ) which tells the lua "parser" that the " is not the end of the string but just a " inside the string.

file:write("print("hello")")

Becomes:

file:write("print("hello")")

Alternately if you are going to be doing multiple lines I recommend using multi-line strings,
multi-line strings are identified using [[ & ]] instead of " which allows you to use un-escaped " inside them,
Like so:


local code = [[
while true do
  print("lol")
end
]]
file:write(code)
Luanub #4
Posted 22 March 2012 - 07:56 AM
Ya I didnt think about that. You can also make it a literal string like…


file:write('shell.run("program_name")"')
BigSHinyToys #5
Posted 22 March 2012 - 04:57 PM
Thank you tomass1996 it works now.


node program form GP-IP ver ALPHA 0.2 – ignore the fact is says o.1 in the code havent released it yet.
When you run it near GPS servers (at least 4) it will automatically create a startup program and a config file. must be in computers root.
Spoiler

--[[
-- This is the startup program that is installed by Node.
startVer = 0.1
print("inisilizing node")
if fs.exists("install") then
print("installed new ver of Node")
fs.delete("node")
fs.move("install","node")
end
while true do
sleep(2)
local value1, value2 = shell.run("node")
if value1 == nil then
print("nil")
else
print(value1)
end
if value2 == nil then
print("nil")
else
print(value2)
end
if value1 then break end
end
-- end of
]]--
nodeVer = 0.1
if fs.exists("startup") == false then
print("installing startup")
local tempStore = {}
local q2 = 0
local file = io.open("node","r")
while true do
q2 = q2+1
tempStore[q2] = file:read()
if q2 == 27 then break end
end
file:close()
local file = io.open( "startup", "w" )
q2 = 1
while true do
q2 = q2+1
file:write(tempStore[q2].."n")
if q2 == 27 then break end
end
file:close()
print("rebooting")
sleep(2)
os.reboot()
end
local x,y,z
rednet.open("top")
if fs.exists("config") then
print("loading config")
file = io.open("config","r")
x = 0
x = file:read()
y = file:read()
z = file:read()
file:close()
print("config loaded")
else
print("no config finding location")
x,y,z = gps.locate( 2, true )
end
if x == nil or y == nil or z == nil then
local runagain = true
while runagain do
  term.clear()
  term.setCursorPos(1,1)
  print("please enter the X Y Z as auto location failed")
  print("or type >exit< to end with out the ><")
  write(" X : ")x = io.read()
  if x == "exit" then error()
  else
  x = tonumber(x)
  end
  write(" y : ")y = tonumber(io.read())
  if y == "exit" then error()
  else
  y = tonumber(y)
  end
  write(" z : ")z = tonumber(io.read())
  if z == "exit" then error()
  else
  z = tonumber(z)
  end
  if x == nil or y == nil or z == nil then
   runagain = true
  else
   runagain = false
  end
end
end
-- save config
if fs.exists("config") == false then
if x ~= nil and y ~= nil and z ~= nil then
print("Config created")
file = io.open("config","w")
file:write(x.."n")
file:write(y.."n")
file:write(z.."n")
file:close()
end
end

testmod = true  -- this turns on and off certin print functions --
local computersID = {}
local computersX = {}
local computersY = {}
local computersZ = {}
local computersM = {}
local computersW = {} -- used for detection of down nodes --
local nodesID = {}
local nodesX = {}
local nodesY = {}
local nodesZ = {}
local nodesM = {}
local nodesW = {} -- used for detection of down nodes --
local packetsID = {}
local packetsTM = {}
local packetsD = {}
local loger = {}
local value = ""
local function rmsin(inf)
inf = tostring(inf)
if string.byte(inf,1) == 45 then
  inf = string.sub(inf,2,string.len(inf))
end
return tonumber(inf)
end
local function checkFor(this,inhere)
local loopn = 0
local maxedn = table.maxn(inhere)
while true do
  if maxedn == loopn then
  return nil
  end
  loopn = loopn+1
  if inhere[loopn] == this then
  return loopn
  end
end
end
local function stringLocator(acton,looking,stpos)
local tempvar = tonumber(stpos)
if tempvar == nil then tempvar = 1 end
local this = string.byte(looking)
local endof = string.len(acton)
while true do
if string.byte(acton,tempvar) == this then
return tempvar
end
if tempvar == endof then return end
tempvar = tempvar + 1
end
end
local function decodeIP(pxq)  -- this takes a string eg "1001.22030.11.12" and decodes it to 1001 22030 11 12 eatch
local tabel = {}

local st = tostring(pxq)  -- a seprate value to be added to a routing table latter
start = 1 -- start pos of where to look for the charicter "."
loc = 0 -- this tracks where the last . was found so it will look further along
fin = string.len(st) -- this is the end position to look to.
local pass = 1 -- when pass = 4 the function will be made to return ( not yet coded ) --
while true do  -- break down loop takes string apart
  local loc = stringLocator(st,".",start)  -- finds the closes "."  this is where the probblems begin
  if loc == nil then
   tabel[pass] = (string.sub(st,start,fin))
  else
   tabel[pass] = (string.sub(st,start,loc-1))
   start = loc+1
  end
if pass == 4 then break end
pass = pass + 1
end
return tonumber(tabel[1]),tonumber(tabel[2]),tonumber(tabel[3]),tonumber(tabel[4])
end

local nextAlam = os.startTimer(120 + math.random(1,30))
rednet.broadcast("REG-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
sleep(0.1)
while true do -- main loop -- this recives a message in this format	"REG-COM 100.202.100.12"   and should act acordinly.
local event, var1, var2, var3, var4, var5 = os.pullEventRaw()
local handled = false

if event == "char" and var1 == "q" then
  print("closing down")
  sleep(3)
  term.clear()
  term.setCursorPos(1,1)
  return"exit"
end

if event == "timer" then
  if var1 == nextAlam then
   print("refreshing nodes list")
   rednet.broadcast("REG-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
   nextAlam = os.startTimer(120 + math.random(1,30))
   sleep(0.1)
  else
   local position2 = checkFor(var1,packetsTM)
   if position2 == nil then
   else
	local position = packetsID[position2] -- position is now the ID of the omputer
	local masterloc = checkFor(position,nodesID)
	if masterloc == nil then
	else
	 if nodesW[masterloc] == "true" then
	  print("removing node"..nodesID[masterloc])
	  table.remove(nodesID,masterloc)
	  table.remove(nodesX,masterloc)
	  table.remove(nodesY,masterloc)
	  table.remove(nodesZ,masterloc)
	  table.remove(nodesM,masterloc)
	  table.remove(nodesW,masterloc)
	  event = "rednet_message"				 ---- experimental
	  var1 = packetsID[position2]
	  var2 = packetsD[position2]
	  table.remove(packetsID,position2)
	  table.remove(packetsTM,position2)
	  table.remove(packetsD,position2)		 ---- very experimental
	 end
	end
	table.remove(packetsID,position2)
	table.remove(packetsTM,position2)
	table.remove(packetsD,position2)
   end
  end
end

if event == "rednet_message" then

  table.insert(loger,"r-net mess from "..var1.." contence "..var2)
  if var2 == "PING" then
   rednet.send(tonumber(var1)+1-1, textutils.serialize({x,y,z}))
   handled = true
  end

  value = string.sub(var2,1,7)

  if value == "PING2--" then
  
   rednet.send(tonumber(var1)+1-1,"OPN-NOD "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
   handled = true
  end

  if value == "REG-COM" then
   print("regstering computer")
   local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2)))
   if checkFor(id4,computersID) == nil then
	print(x4.." "..y4.." "..z4.." "..id4)
	local newentry = table.maxn(computersID)+1
	computersID[newentry] = tonumber(id4)  -- i dont need the tonumbers
	computersX[newentry] = tonumber(x4)
	computersY[newentry] = tonumber(y4)
	computersZ[newentry] = tonumber(z4)
	computersM[newentry] = tonumber(var3)
	computersW[newentry] = "false"
   else
	print("compuer already reged")
   end
  
   rednet.send(tonumber(var1)+1-1,"REG-RPL "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
   handled = true
  end

  if value == "REG-RPL" then
   print("reciving reply")
   local x4,y4,z4,id4 = decodeIP(string.sub(var2,9,string.len(var2)))
   if checkFor(id4,computersID) == nil then
	print(x4.." "..y4.." "..z4.." "..id4)
	local newentry = table.maxn(computersID)+1
	computersID[newentry] = tonumber(id)  -- i dont need the tonumbers
	computersX[newentry] = tonumber(x4)
	computersY[newentry] = tonumber(y4)
	computersZ[newentry] = tonumber(z4)
	computersM[newentry] = tonumber(var3)
	computersW[newentry] = "false"
   else
	print("computer already reged")
   end
   handled = true
  end

  if value == "INSTALL" then
   local tempvar = string.sub(var2,9)
   file = io.open("install","w")
   file:write(tempvar)
   file:close()
   print(tempvar)
   print("bellow temp var")
   sleep(0.5)
   os.reboot()
   sleep(0.5)
   handled = true
  end


  if value == "REG-NOD" then -- this will be used latter for simlor perpous to above if statment
   print("regstering Node")
   x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2)))
   if checkFor(id6,nodesID) == nil then
	print(x6.." "..y6.." "..x6.." "..id6)
	local newentry = table.maxn(nodesID)+1
	nodesID[newentry] = tonumber(id6) -- i dont need the tonumbers
	nodesX[newentry] = tonumber(x6)
	nodesY[newentry] = tonumber(y6)
	nodesZ[newentry] = tonumber(z6)
	nodesM[newentry] = tonumber(var3)
	nodesW[newentry] = "false"
   else
	print("node already reged")
   end
  
   print("replying to :"..var1)
   rednet.send(tonumber(var1+1-1),"REGNRPL "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
   handled = true
  end

  if value == "REGNRPL" then -- this will be used latter for simlor perpous to above if statment
   print("node replyed to reg")
   x6,y6,z6,id6 = decodeIP(string.sub(var2,9,string.len(var2)))
   if checkFor(id6,nodesID) == nil then
	print(x6.." "..y6.." "..x6.." "..id6)
	local newentry = table.maxn(nodesID)+1
	nodesID[newentry] = tonumber(id6) -- i dont need the tonumbers
	nodesX[newentry] = tonumber(x6)
	nodesY[newentry] = tonumber(y6)
	nodesZ[newentry] = tonumber(z6)
	nodesM[newentry] = tonumber(var3)
	nodesW[newentry] = "false"
   else
	print("node already reged")
   end
   handled = true
  end

  if value == "S-ALIVE" then  -- this is part of the is node alive check system.
   if checkFor(var1,nodesID) ~= nill then
   local row = checkFor(var1,nodesID)
   nodesW[row] = "false" -- node is still alive --
   end
   handled = true
   print(var1.." Is still around")
  end

  if tonumber(var1) == os.getComputerID() then
   handled = true
  end

  if handled == false then
   local pos1 = stringLocator(var2," ")
   local x1,y1,z1,id1 = decodeIP(string.sub(var2,1,pos1-1))
   local pos2 = stringLocator(var2," ",pos1+1)
   local x2,y2,z2,id2 = decodeIP(string.sub(var2,pos1+1,pos2-1))
   payload = string.sub(var2,pos2+1,string.len(var2))
   if x1 == nil or y1 == nil or z1 == nil or id1 == nil or x2 == nil or y2 == nil or z2 == nil or id2 == nil then
	print("Network error 05 - Packet not corect format")
   else
	if testmod == true then  -- TEST FLAG
	 print(payload)
	 print("from: "..x1.." "..y1.." "..z1.." "..id1)
	 print("for : "..x2.." "..y2.." "..z2.." "..id2)
	end  -- end TEST FLAG
	local test = checkFor(id2,computersID)
	if test == nil then
	 local test = checkFor(id2,nodesID)
	 if test == nil then
	  print("cant send direct")  -- find closest node and send there after printing
	  local loopz = 1
	  local bestM = nil
	  local sendID = nil
	  while true do
	   if nodesID[loopz] == id2 then
		print("cant send back to sorce, will keep looking")
	   else
		local tp1 = x2 - nodesX[loopz]
		local tp2 = y2 - nodesY[loopz]
		local tp3 = math.sqrt((tp1^2) + (tp2^2))
		local tp4 = z2 - nodesZ[loopz]
		local tp5 = math.sqrt(tp3^2 + tp4^2)
		print (nodesID[loopz].." is meters : "..tp5)
		if bestM == nil then
		 bestM = tp5
		 sendID = nodesID[loopz]
		 else
		 if bestM > tp5 then
		 bestM = tp5
		 sendID = nodesID[loopz]
		 print("new best is "..sendID.." M - "..bestM)
		 end
		end
	  
	   end
	   if loopz == table.maxn(nodesID) then break end
	   loopz = loopz+1
	  end
	   if sendID == nil then
		print("sending to nil ")
	   end
	  sendID = math.ceil(sendID)
	  rednet.send(sendID,var2)
	  print("packet sent to M1 :"..sendID)
	  local blue = tonumber(checkFor(sendID,nodesID))
	  nodesW[blue] = "true"
	
	  rednet.send(tonumber(var1),"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
	  print("Relpy to node: "..tonumber(var1))
	  local o = table.maxn(packetsID)+1
	  packetsID[o] = sendID
	  packetsTM[o] = os.startTimer(10)
	  packetsD[o] = var2
	 else
	  rednet.send(nodesID[test],var2)
	  nodesW[test] = "true"
	  print("sending to node : "..nodesID[test])
	
	  rednet.send(tonumber(var1),"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
	  print("Replyed to: "..tonumber(var1))
	  o = table.maxn(packetsID)+1
	  packetsID[o] = nodesID[test]
	  packetsTM[o] = os.startTimer(10)
	  packetsD[o] = var2
	 end
	else
	 test = tonumber(test)
	 rednet.send(tonumber(computersID[test])+1-1,var2)
	 print("sending to comp : "..computersID[test])
	
	 rednet.send(tonumber(var1)+1-1,"S-ALIVE "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
	 print("sent reply node "..var1)
	end
  
   end

  end

end

if event == "char" then  -- char events . mostly tests

  if var1 == "t" then
   term.clear()
   term.setCursorPos(1,1)
   local loops = 0
   while true do
	if loops == table.maxn(computersID) then
	 print("end of Computer table")
	 break
	end
	loops = loops +1
	print("entry "..loops.."  : "..computersID[loops].."  X "..computersX[loops].."  Y "..computersY[loops].."  Z "..computersZ[loops].."  M "..computersM[loops])
   end
  end

  if var1 == "y" then
   term.clear()
   term.setCursorPos(1,1)
   local loops = 0
   while true do
	if loops == table.maxn(nodesID) then
	 print("end of Nodes table")
	 break
	end
	loops = loops +1
	print("entry "..loops.."  : "..nodesID[loops].."  X "..nodesX[loops].."  Y "..nodesY[loops].."  Z "..nodesZ[loops].."  M "..nodesM[loops])
   end
  end

  if var1 == "u" then
   term.clear()
   term.setCursorPos(1,1)
   local loops = 0
   while true do
	if loops == table.maxn(packetsID) then
	 print("end of packets")
	 break
	end
	loops = loops +1
	print("entry "..loops.."  : "..packetsID[loops].."  : "..tostring(packetsTM[loops]).."  : "..packetsD[loops])
   end
  end

  if var1 == "r" then
   loops = 0
   term.clear()
   term.setCursorPos(1,1)
   print("This is Node ver"..tostring(nodeVer).." : "..tostring(x).."."..tostring(y).."."..tostring(z).."."..tostring(os.getComputerID()))
   while true do
	if loops == table.maxn(loger) then
	 print("end of log")
	 break
	end
	loops = loops +1
	print("entry "..loops.."  : "..loger[loops])
   end

  end
end   -- end of char events
end
Hawk777 #6
Posted 24 March 2012 - 07:14 AM
Note that instead of manually escaping quotation marks and stuff, you can use the “string.format” function with the “%q” option. See http://www.lua.org/manual/5.1/manual.html#5.4.
DrunkenMasta #7
Posted 08 June 2012 - 12:55 PM
A simpler way is to change the double quotes to single quotes …
That way it won't mess up your code


file:write("print('wassup?')")
BigSHinyToys #8
Posted 08 June 2012 - 04:23 PM
a ) this is a necro
b ) I have used multi line quote eg

The bellow code is the real startup file from node ver 5 all rights NOT reserved. do with it what ever you would like.

if fs.exists("startup") == false then
sStartup = [[
-- This is the startup program that is installed by Node.
startVer = 0.1
print("Initializing node")
if fs.exists("install") then
print("installed new ver of Node")
fs.delete("node")
fs.move("install","node")
end
while true do
sleep(2)
local value1, value2 = shell.run("node")
if value1 == nil then
print("nil")
else
print(value1)
end
if value2 == nil then
print("nil")
else
print(value2)
end
if value1 then break end
end
-- end of
]]
print("Installing startup")
local file = io.open( "startup", "w" )
file:write(sStartup)
file:close()
print("Rebooting in 3 seconds")
sleep(3)
os.reboot()
else
sStartup = nil
end

[EDIT]
FYI, you probably mean "Initializing".
fixed
[/EDIT]
Lyqyd #9
Posted 08 June 2012 - 06:40 PM
FYI, you probably mean "Initializing".