-- LocalScript for auto-injecting a Linux-themed GUI with screenfetch style, Lua
execution, and Linux commands
local player = game.Players.LocalPlayer
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
-- Function to create and inject the GUI
local function createGUI()
-- Clean up any existing GUI to avoid duplicates
local existingGui = player.PlayerGui:FindFirstChild("LinuxThemedGUI")
if existingGui then
existingGui:Destroy()
end
-- Mock file system
local fileSystem = {
["/roblox/home/" .. player.Name] = {
["info.txt"] = "Welcome to TuxTerm!",
["scripts"] = {}
}
}
local currentDir = "/roblox/home/" .. player.Name
-- Command history
local commandHistory = {}
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "LinuxThemedGUI"
screenGui.Parent = player.PlayerGui
-- Main frame
local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 600, 0, 400)
mainFrame.Position = UDim2.new(0.5, -300, 0.5, -200)
mainFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
mainFrame.BorderSizePixel = 0
mainFrame.Parent = screenGui
-- Border
local border = Instance.new("UIStroke")
border.Color = Color3.fromRGB(100, 100, 100)
border.Thickness = 2
border.Parent = mainFrame
-- Title bar
local titleBar = Instance.new("Frame")
titleBar.Size = UDim2.new(1, 0, 0, 30)
titleBar.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
titleBar.BorderSizePixel = 0
titleBar.Parent = mainFrame
-- Title text
local titleText = Instance.new("TextLabel")
titleText.Size = UDim2.new(1, -100, 1, 0)
titleText.Position = UDim2.new(0, 40, 0, 0)
titleText.BackgroundTransparency = 1
titleText.Text = "Linux Lua Terminal"
titleText.TextColor3 = Color3.fromRGB(200, 200, 200)
titleText.TextSize = 16
titleText.Font = Enum.Font.Ubuntu
titleText.TextXAlignment = Enum.TextXAlignment.Left
titleText.Parent = titleBar
-- Tux logo in title bar
local tuxImage = Instance.new("ImageLabel")
tuxImage.Size = UDim2.new(0, 24, 0, 24)
tuxImage.Position = UDim2.new(0, 5, 0, 3)
tuxImage.BackgroundTransparency = 1
tuxImage.Image = "rbxassetid://103195905599660"
tuxImage.Parent = titleBar
-- Close button
local closeButton = Instance.new("TextButton")
closeButton.Size = UDim2.new(0, 20, 0, 20)
closeButton.Position = UDim2.new(1, -25, 0, 5)
closeButton.BackgroundColor3 = Color3.fromRGB(255, 100, 100)
closeButton.BorderSizePixel = 0
closeButton.Text = ""
closeButton.Parent = titleBar
closeButton.MouseButton1Click:Connect(function()
screenGui:Destroy()
end)
-- ASCII art (Tux) on left
local asciiArt = Instance.new("TextLabel")
asciiArt.Size = UDim2.new(0, 200, 0, 150)
asciiArt.Position = UDim2.new(0, 10, 0, 40)
asciiArt.BackgroundTransparency = 1
asciiArt.Text = [[
,@@@@@@@,
,@@, ,@@,
@@, ,@@,
@@, ,@@,
@@, ,@@,
@@, ,@@,
@@, ,@@,
,@@, ,@@,
,@@@@@@@,
]]
asciiArt.TextColor3 = Color3.fromRGB(0, 191, 255)
asciiArt.TextSize = 12
asciiArt.Font = Enum.Font.Code
asciiArt.TextWrapped = true
asciiArt.Parent = mainFrame
-- System info on right
local systemInfo = Instance.new("TextLabel")
systemInfo.Size = UDim2.new(0, 350, 0, 150)
systemInfo.Position = UDim2.new(0, 220, 0, 40)
systemInfo.BackgroundTransparency = 1
systemInfo.TextColor3 = Color3.fromRGB(0, 255, 0)
systemInfo.TextSize = 12
systemInfo.Font = Enum.Font.Code
systemInfo.TextWrapped = true
systemInfo.Text = "OS: RobloxOS 1.0\nKernel: rbx_kernel 1.0\nUptime: 0 mins\
nPackages: 100\nShell: rbx_bash 1.0\nResolution: 800x600\nDE: RobloxDE 1.0\nWM:
rbx_WM\nGTK Theme: TuxTheme\nDisk: 50% used\nCPU: Roblox CPU @ 2.0GHz\nGPU: Roblox
GPU\nRAM: 512MB / 1024MB"
systemInfo.Parent = mainFrame
-- Update system info dynamically
game:GetService("RunService").Heartbeat:Connect(function()
local uptime = math.floor(tick() / 60)
local ramUsage = math.min(#Players:GetPlayers() * 50, 512)
systemInfo.Text = string.format("OS: RobloxOS 1.0\nKernel: rbx_kernel 1.0\
nUptime: %d mins\nPackages: 100\nShell: rbx_bash 1.0\nResolution: 800x600\nDE:
RobloxDE 1.0\nWM: rbx_WM\nGTK Theme: TuxTheme\nDisk: 50%% used\nCPU: Roblox CPU @
2.0GHz\nGPU: Roblox GPU\nRAM: %dMB / 1024MB", uptime, ramUsage)
end)
-- Terminal box
local terminalBox = Instance.new("TextBox")
terminalBox.Size = UDim2.new(0.95, 0, 0.35, 0)
terminalBox.Position = UDim2.new(0.025, 0, 0.45, 0)
terminalBox.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
terminalBox.TextColor3 = Color3.fromRGB(0, 255, 0)
terminalBox.TextSize = 14
terminalBox.Font = Enum.Font.Ubuntu
terminalBox.Text = "$ sudo "
terminalBox.TextXAlignment = Enum.TextXAlignment.Left
terminalBox.TextYAlignment = Enum.TextYAlignment.Top
terminalBox.ClearTextOnFocus = false
terminalBox.MultiLine = true
terminalBox.Parent = mainFrame
-- Output box
local outputBox = Instance.new("TextLabel")
outputBox.Size = UDim2.new(0.95, 0, 0.15, 0)
outputBox.Position = UDim2.new(0.025, 0, 0.82, 0)
outputBox.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
outputBox.TextColor3 = Color3.fromRGB(255, 255, 255)
outputBox.TextSize = 12
outputBox.Font = Enum.Font.Ubuntu
outputBox.Text = "Output: "
outputBox.TextXAlignment = Enum.TextXAlignment.Left
outputBox.TextYAlignment = Enum.TextYAlignment.Top
outputBox.TextWrapped = true
outputBox.Parent = mainFrame
-- Execute button
local executeButton = Instance.new("TextButton")
executeButton.Size = UDim2.new(0.3, 0, 0.1, 0)
executeButton.Position = UDim2.new(0.35, 0, 0.98, -20)
executeButton.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
executeButton.TextColor3 = Color3.fromRGB(200, 200, 200)
executeButton.Text = "Execute"
executeButton.TextSize = 14
executeButton.Font = Enum.Font.Ubuntu
executeButton.Parent = mainFrame
-- Store captured output
local capturedOutput = {}
-- Custom print function
local function customPrint(...)
local args = {...}
local output = ""
for i, v in ipairs(args) do
output = output .. tostring(v) .. (i < #args and " " or "")
end
table.insert(capturedOutput, output)
print(...)
end
-- Process Linux commands
local function processLinuxCommand(command, args)
command = command:lower()
table.insert(commandHistory, "$ sudo " .. command .. (args ~= "" and " " ..
args or ""))
if command == "ls" or command == "dir" then
local players = {}
for _, p in ipairs(Players:GetPlayers()) do
table.insert(players, p.Name)
end
return table.concat(players, " ")
elseif command == "cd" then
if args == "" or args == "~" then
currentDir = "/roblox/home/" .. player.Name
return "Changed directory to " .. currentDir
elseif fileSystem[currentDir .. "/" .. args] then
currentDir = currentDir .. "/" .. args
return "Changed directory to " .. currentDir
else
return "cd: " .. args .. ": No such directory"
end
elseif command == "pwd" then
return currentDir
elseif command == "cat" then
if args == "" then
return "cat: Missing file operand"
end
local fileContent = fileSystem[currentDir] and fileSystem[currentDir]
[args]
if type(fileContent) == "string" then
return fileContent
else
return "cat: " .. args .. ": No such file"
end
elseif command == "mkdir" then
if args == "" then
return "mkdir: Missing directory name"
end
fileSystem[currentDir] = fileSystem[currentDir] or {}
fileSystem[currentDir][args] = {}
return "Created directory " .. args
elseif command == "rm" then
if args == "" then
return "rm: Missing operand"
end
if fileSystem[currentDir] and fileSystem[currentDir][args] then
fileSystem[currentDir][args] = nil
return "Removed " .. args
else
return "rm: " .. args .. ": No such file or directory"
end
elseif command == "touch" then
if args == "" then
return "touch: Missing file name"
end
fileSystem[currentDir] = fileSystem[currentDir] or {}
fileSystem[currentDir][args] = ""
return "Created file " .. args
elseif command == "echo" then
if args == "$USER" then
return player.Name
elseif args == "" then
return "ECHO is on."
else
return args
end
elseif command == "man" then
if args == "" then
return "man: Missing command name"
elseif args == "ls" or args == "dir" then
return "ls: List players in the game"
elseif args == "cd" then
return "cd: Change mock directory"
elseif args == "pwd" then
return "pwd: Print working directory"
elseif args == "cat" then
return "cat: Display mock file contents"
elseif args == "mkdir" then
return "mkdir: Create a mock directory"
elseif args == "rm" then
return "rm: Remove a mock file or directory"
elseif args == "touch" then
return "touch: Create an empty mock file"
elseif args == "echo" then
return "echo: Display text or variables"
elseif args == "man" then
return "man: Show manual for a command"
elseif args == "uptime" then
return "uptime: Show server uptime"
elseif args == "ps" then
return "ps: List mock processes (players)"
elseif args == "kill" then
return "kill: Simulate terminating a process"
elseif args == "chmod" then
return "chmod: Simulate changing permissions"
elseif args == "grep" then
return "grep: Simulate searching text"
elseif args == "find" then
return "find: Simulate searching for files"
elseif args == "df" then
return "df: Show mock disk usage"
elseif args == "du" then
return "du: Show mock directory size"
elseif args == "top" then
return "top: Show mock system resource usage"
elseif args == "history" then
return "history: Show command history"
else
return "man: No manual entry for " .. args
end
elseif command == "uptime" then
local uptime = math.floor(tick() / 60)
return "Uptime: " .. uptime .. " mins"
elseif command == "ps" then
local processes = {}
for _, p in ipairs(Players:GetPlayers()) do
table.insert(processes, p.Name .. " (PID: " .. math.random(1000,
9999) .. ")")
end
return table.concat(processes, "\n")
elseif command == "kill" then
if args == "" then
return "kill: Missing process ID"
end
return "Terminated process " .. args
elseif command == "chmod" then
if args == "" then
return "chmod: Missing permissions or file"
end
return "Changed permissions for " .. args
elseif command == "grep" then
if args == "" then
return "grep: Missing pattern"
end
return "Found: " .. args .. " in mock data"
elseif command == "find" then
if args == "" then
return "find: Missing search criteria"
end
local results = {}
for path, dir in pairs(fileSystem) do
for name, _ in pairs(dir) do
if name:match(args) then
table.insert(results, path .. "/" .. name)
end
end
end
return table.concat(results, "\n") or "No files found"
elseif command == "df" then
return "Filesystem: Roblox\nUsed: 50%\nAvailable: 50%"
elseif command == "du" then
local size = 0
for _, dir in pairs(fileSystem[currentDir] or {}) do
size = size + (type(dir) == "string" and #dir or 10)
end
return "Size: " .. size .. " bytes"
elseif command == "top" then
return "CPU: " .. #Players:GetPlayers() .. "%\nMem: 50%\nPlayers: " ..
#Players:GetPlayers()
elseif command == "history" then
return table.concat(commandHistory, "\n")
elseif command == "clear" then
terminalBox.Text = "$ sudo "
return "Cleared"
elseif command == "whoami" then
return "User: " .. player.Name
elseif command == "help" then
return "Commands: clear, whoami, help, ls, dir, cd, pwd, cat, mkdir,
rm, touch, echo, man, uptime, ps, kill, chmod, grep, find, df, du, top, history\
nEnter Lua code to execute"
else
return nil
end
end
-- Function to safely execute Lua code
local function executeLuaCode(code)
capturedOutput = {}
local env = getfenv()
env.print = customPrint
local cleanCode = code:gsub("%$ sudo ", "")
if loadstring then
local func, err = loadstring(cleanCode)
if func then
setfenv(func, env)
local success, result = pcall(func)
if not success then
return false, "Runtime error: " .. tostring(result),
capturedOutput
end
local outputStr = table.concat(capturedOutput, "\n")
return true, result and tostring(result) or (outputStr ~= "" and
outputStr or "Executed successfully"), capturedOutput
else
return false, "Syntax error: " .. tostring(err), capturedOutput
end
else
return false, "loadstring not available", capturedOutput
end
end
-- Execute button functionality
executeButton.MouseButton1Click:Connect(function()
local code = terminalBox.Text
if code == "" or code == "$ sudo " then
outputBox.Text = "Output: No code entered"
return
end
local cleanCode = code:lower():gsub("%$ sudo ", "")
local command, args = cleanCode:match("^(%S+)%s*(.*)")
command = command or cleanCode
args = args or ""
local linuxOutput = processLinuxCommand(command, args)
if linuxOutput then
outputBox.Text = "Output: " .. linuxOutput
return
end
local success, result, outputs = executeLuaCode(code)
table.insert(commandHistory, code)
local outputStr = table.concat(outputs, "\n")
if success then
outputBox.Text = "Output: " .. (outputStr ~= "" and outputStr or
result)
else
outputBox.Text = "Error: " .. result .. (outputStr ~= "" and "\n" ..
outputStr or "")
end
end)
-- Add $ sudo prefix on new lines
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.KeyCode == Enum.KeyCode.Return and terminalBox:IsFocused() then
local currentText = terminalBox.Text
local cursorPos = terminalBox.CursorPosition
local lines = currentText:split("\n")
local currentLineIndex = #lines
if cursorPos > 0 then
local charCount = 0
for i, line in ipairs(lines) do
charCount = charCount + #line + 1
if charCount >= cursorPos then
currentLineIndex = i
break
end
end
end
local newText = currentText .. "\n$ sudo "
terminalBox.Text = newText
terminalBox.CursorPosition = #newText + 1
end
end)
-- Prevent deleting initial $ sudo
terminalBox:GetPropertyChangedSignal("Text"):Connect(function()
if not terminalBox.Text:match("^%$ sudo ") then
terminalBox.Text = "$ sudo " .. terminalBox.Text
terminalBox.CursorPosition = #terminalBox.Text + 1
end
end)
-- Dragging functionality
local dragging = false
local dragStart = nil
local startPos = nil
titleBar.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
dragging = true
dragStart = input.Position
startPos = mainFrame.Position
end
end)
titleBar.InputChanged:Connect(function(input)
if dragging and input.UserInputType == Enum.UserInputType.MouseMovement
then
local delta = input.Position - dragStart
mainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset +
delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
end)
titleBar.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
dragging = false
end
end)
-- Shadow effect
local shadow = Instance.new("UIStroke")
shadow.Color = Color3.fromRGB(0, 0, 0)
shadow.Thickness = 3
shadow.Transparency = 0.5
shadow.Parent = mainFrame
end
-- Create GUI when player joins or respawns
player.CharacterAdded:Connect(createGUI)
-- Create GUI immediately if character already exists
if player.Character then
createGUI()
end