Running Long-Running Asynchronous Tasks
Running long-term background tasks in Linux sandboxes using systemd
This documentation applies to Linux sandboxes. If you are using a Windows sandbox, please refer to Running Long-Running Tasks in Windows Sandboxes.
In Lybic sandboxes, you may need to run long-executing tasks such as model training, data processing, or web servers. Since the execSandboxProcess API has timeout limits and does not support background execution, we recommend using systemd --user run to execute such tasks.
Tip: For quick-running short commands (completing within 5 seconds), please use the execSandboxProcess API.
How It Works
systemd --user run creates a temporary systemd service unit (transient unit) that automatically cleans up after the task completes. The task runs under systemd's management, decoupled from the API call.
Usage
Step Overview
- Prepare script or program: Transfer the script/program to the sandbox
- Start task: Use
systemd --user runto start the long-running task - Check status: Query the task's running status and logs
Step 1: Prepare Script or Program
There are two ways to prepare the script or program to run:
Method A: File Copy
Upload the script to the sandbox using the File Transfer API:
# First, upload the script to object storage (get download URL)
# Then, download to sandbox from URL
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/file/copy" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"files": [
{
"id": "upload-training-script",
"src": {
"type": "httpGetLocation",
"url": "https://storage.example.com/scripts/train.py"
},
"dest": {
"type": "sandboxFileLocation",
"path": "/home/agent/scripts/train.py"
}
}
]
}'import asyncio
from lybic import LybicClient, LybicAuth
from lybic.dto import (
SandboxFileCopyRequestDto,
FileCopyItem,
SandboxFileLocation,
HttpGetLocation
)
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
# Upload script to sandbox
await client.sandbox.copy_files(
"SBX-xxxx",
SandboxFileCopyRequestDto(files=[
FileCopyItem(
id="upload-training-script",
src=HttpGetLocation(
url="https://storage.example.com/scripts/train.py"
),
dest=SandboxFileLocation(
path="/home/agent/scripts/train.py"
)
)
])
)
print("Script uploaded successfully")
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
// Upload script to sandbox
await lybic.copyFilesWithSandbox('SBX-xxxx', {
files: [
{
id: 'upload-training-script',
src: {
type: 'httpGetLocation',
url: 'https://storage.example.com/scripts/train.py',
},
dest: {
type: 'sandboxFileLocation',
path: '/home/agent/scripts/train.py',
},
},
],
})
console.log('Script uploaded successfully')package main
import (
"context"
"fmt"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
copyDto := lybic.SandboxFileCopyRequestDto{
Files: []lybic.SandboxFileCopyRequestDtoFiles{
{
Id: "upload-training-script",
Src: map[string]string{
"type": "httpGetLocation",
"url": "https://storage.example.com/scripts/train.py",
},
Dest: map[string]any{
"type": "sandboxFileLocation",
"path": "/home/agent/scripts/train.py",
},
},
},
}
_, err := client.CopyFilesWithSandbox(ctx, "SBX-xxxx", copyDto)
if err != nil {
fmt.Println("Error uploading script:", err)
return
}
fmt.Println("Script uploaded successfully")
}Method B: Write via stdin
Use execSandboxProcess to pipe script content to a file:
# Base64 encode script content
SCRIPT_CONTENT=$(cat << 'EOF' | base64 -w0
#!/usr/bin/env python3
import time
import sys
print("Starting model training...")
for i in range(100):
time.sleep(1)
print(f"Progress: {i+1}/100")
sys.stdout.flush()
print("Training completed!")
EOF
)
# Write to file
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/process" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"executable": "bash",
"args": ["-c", "cat > /home/agent/scripts/train.py && chmod +x /home/agent/scripts/train.py"],
"stdinBase64": "'$SCRIPT_CONTENT'"
}'import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
# Prepare script content
script_content = """#!/usr/bin/env python3
import time
import sys
print("Starting model training...")
for i in range(100):
time.sleep(1)
print(f"Progress: {i+1}/100")
sys.stdout.flush()
print("Training completed!")
"""
# Base64 encode
stdin_data = base64.b64encode(script_content.encode()).decode()
# Write to file and add execute permission
result = await client.sandbox.execute_process(
"SBX-xxxx",
executable="bash",
args=["-c", "cat > /home/agent/scripts/train.py && chmod +x /home/agent/scripts/train.py"],
stdinBase64=stdin_data
)
if result.exitCode == 0:
print("Script created successfully")
else:
print(f"Creation failed: {base64.b64decode(result.stderrBase64 or '').decode()}")
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
// Prepare script content
const scriptContent = `#!/usr/bin/env python3
import time
import sys
print("Starting model training...")
for i in range(100):
time.sleep(1)
print(f"Progress: {i+1}/100")
sys.stdout.flush()
print("Training completed!")
`
// Base64 encode
const stdinBase64 = btoa(scriptContent)
// Write to file and add execute permission
const result = await lybic.execSandboxProcess('SBX-xxxx', {
executable: 'bash',
args: ['-c', 'cat > /home/agent/scripts/train.py && chmod +x /home/agent/scripts/train.py'],
stdinBase64: stdinBase64,
})
if (result.data?.exitCode === 0) {
console.log('Script created successfully')
} else {
console.log('Creation failed:', atob(result.data?.stderrBase64 || ''))
}package main
import (
"context"
"encoding/base64"
"fmt"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
// Prepare script content
scriptContent := `#!/usr/bin/env python3
import time
import sys
print("Starting model training...")
for i in range(100):
time.sleep(1)
print(f"Progress: {i+1}/100")
sys.stdout.flush()
print("Training completed!")
`
// Base64 encode
stdinBase64 := base64.StdEncoding.EncodeToString([]byte(scriptContent))
// Write to file and add execute permission
cmd := "cat > /home/agent/scripts/train.py && chmod +x /home/agent/scripts/train.py"
processDto := lybic.SandboxProcessRequestDto{
Executable: "bash",
Args: []string{"-c", cmd},
StdinBase64: &stdinBase64,
}
result, _ := client.ExecSandboxProcess(ctx, "SBX-xxxx", processDto)
if result.ExitCode == 0 {
fmt.Println("Script created successfully")
} else {
stderr, _ := base64.StdEncoding.DecodeString(result.StderrBase64)
fmt.Printf("Creation failed: %s\n", string(stderr))
}
}Step 2: Start Task Using systemd --user run
Use systemd-run --user to start the long-running task. This command returns immediately while the task continues running in the background.
# Start long-running task
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/process" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"executable": "systemd-run",
"args": [
"--user",
"--unit=my-training-task",
"--description=Model Training Task",
"python3",
"/home/agent/scripts/train.py"
]
}'import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
# Start systemd task
result = await client.sandbox.execute_process(
"SBX-xxxx",
executable="systemd-run",
args=[
"--user",
"--unit=my-training-task",
"--description=Model Training Task",
"python3",
"/home/agent/scripts/train.py"
]
)
output = base64.b64decode(result.stdoutBase64 or '').decode()
print(f"Task started: {output}")
print(f"Exit code: {result.exitCode}")
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
// Start systemd task
const result = await lybic.execSandboxProcess('SBX-xxxx', {
executable: 'systemd-run',
args: [
'--user',
'--unit=my-training-task',
'--description=Model Training Task',
'python3',
'/home/agent/scripts/train.py',
],
})
const output = atob(result.data?.stdoutBase64 || '')
console.log('Task started:', output)
console.log('Exit code:', result.data?.exitCode)package main
import (
"context"
"encoding/base64"
"fmt"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
// Start systemd task
processDto := lybic.SandboxProcessRequestDto{
Executable: "systemd-run",
Args: []string{
"--user",
"--unit=my-training-task",
"--description=Model Training Task",
"python3",
"/home/agent/scripts/train.py",
},
}
result, err := client.ExecSandboxProcess(ctx, "SBX-xxxx", processDto)
if err != nil {
fmt.Println("Error starting task:", err)
return
}
stdout, _ := base64.StdEncoding.DecodeString(result.StdoutBase64)
fmt.Printf("Task started: %s\n", string(stdout))
fmt.Printf("Exit code: %d\n", result.ExitCode)
}Important parameter explanations:
--user: Run in user mode (required)--unit=<name>: Specify unit name for later status queries and log viewing--description=<description>: Task description (optional)- Subsequent parameters are the actual command to execute
Step 3: Check Task Status
3.1 View Task Running Status
Use systemctl --user status to check task running status:
# Check task status
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/process" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"executable": "systemctl",
"args": ["--user", "status", "my-training-task"]
}'import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
# Check task status
result = await client.sandbox.execute_process(
"SBX-xxxx",
executable="systemctl",
args=["--user", "status", "my-training-task"]
)
status = base64.b64decode(result.stdoutBase64 or '').decode()
print("Task status:")
print(status)
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
// Check task status
const result = await lybic.execSandboxProcess('SBX-xxxx', {
executable: 'systemctl',
args: ['--user', 'status', 'my-training-task'],
})
const status = atob(result.data?.stdoutBase64 || '')
console.log('Task status:')
console.log(status)package main
import (
"context"
"encoding/base64"
"fmt"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
// Check task status
processDto := lybic.SandboxProcessRequestDto{
Executable: "systemctl",
Args: []string{"--user", "status", "my-training-task"},
}
result, _ := client.ExecSandboxProcess(ctx, "SBX-xxxx", processDto)
stdout, _ := base64.StdEncoding.DecodeString(result.StdoutBase64)
fmt.Println("Task status:")
fmt.Println(string(stdout))
}Example status output:
● my-training-task.service - Model Training Task
Loaded: loaded (/run/user/1000/systemd/transient/my-training-task.service; transient)
Transient: yes
Active: active (running) since Mon 2024-01-15 10:30:00 UTC; 5min ago
Main PID: 12345 (python3)
Tasks: 1 (limit: 4915)
Memory: 45.2M
CPU: 2.5s
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/my-training-task.service
└─12345 python3 /home/agent/scripts/train.py3.2 View Task Logs
Use journalctl --user to view task output logs:
# View task logs (latest 100 lines)
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/process" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"executable": "journalctl",
"args": [
"--user",
"--unit=my-training-task",
"-n", "100",
"--no-pager"
]
}'import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
# View task logs
result = await client.sandbox.execute_process(
"SBX-xxxx",
executable="journalctl",
args=[
"--user",
"--unit=my-training-task",
"-n", "100",
"--no-pager"
]
)
logs = base64.b64decode(result.stdoutBase64 or '').decode()
print("Task logs:")
print(logs)
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
// View task logs
const result = await lybic.execSandboxProcess('SBX-xxxx', {
executable: 'journalctl',
args: [
'--user',
'--unit=my-training-task',
'-n', '100',
'--no-pager',
],
})
const logs = atob(result.data?.stdoutBase64 || '')
console.log('Task logs:')
console.log(logs)package main
import (
"context"
"encoding/base64"
"fmt"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
// View task logs
processDto := lybic.SandboxProcessRequestDto{
Executable: "journalctl",
Args: []string{
"--user",
"--unit=my-training-task",
"-n", "100",
"--no-pager",
},
}
result, _ := client.ExecSandboxProcess(ctx, "SBX-xxxx", processDto)
stdout, _ := base64.StdEncoding.DecodeString(result.StdoutBase64)
fmt.Println("Task logs:")
fmt.Println(string(stdout))
}Example log output:
Jan 28 06:20:37 agent-machine systemd[877]: Started my-training-task.service - Model Training Task.
Jan 28 06:20:38 agent-machine python3[17083]: Starting model training...
Jan 28 06:20:38 agent-machine python3[17083]: Progress: 1/100
Jan 28 06:20:39 agent-machine python3[17083]: Progress: 2/100
Jan 28 06:20:40 agent-machine python3[17083]: Progress: 3/100
Jan 28 06:20:41 agent-machine python3[17083]: Progress: 4/100
Jan 28 06:20:42 agent-machine python3[17083]: Progress: 5/100
...Common journalctl parameters:
-n <number>: Show the latest N lines of logs-f: Follow logs in real-time (not recommended due to API timeout limits)--no-pager: Output directly without pagination (required)--since "5 minutes ago": Show logs from the last 5 minutes-o json: Output in JSON format
3.3 Check If Task Is Still Running
Use systemctl --user is-active to quickly check task status:
curl -X POST "https://api.lybic.cn/api/orgs/{orgId}/sandboxes/{sandboxId}/process" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"executable": "systemctl",
"args": ["--user", "is-active", "my-training-task"]
}'import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def main():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
result = await client.sandbox.execute_process(
"SBX-xxxx",
executable="systemctl",
args=["--user", "is-active", "my-training-task"]
)
status = base64.b64decode(result.stdoutBase64 or '').decode().strip()
if status == "active":
print("✓ Task is running")
elif status == "inactive":
print("✗ Task has stopped")
else:
print(f"Task status: {status}")
if __name__ == "__main__":
asyncio.run(main())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
const result = await lybic.execSandboxProcess('SBX-xxxx', {
executable: 'systemctl',
args: ['--user', 'is-active', 'my-training-task'],
})
const status = atob(result.data?.stdoutBase64 || '').trim()
if (status === 'active') {
console.log('✓ Task is running')
} else if (status === 'inactive') {
console.log('✗ Task has stopped')
} else {
console.log('Task status:', status)
}package main
import (
"context"
"encoding/base64"
"fmt"
"strings"
"github.com/lybic/lybic-sdk-go"
)
func main() {
ctx := context.Background()
client, _ := lybic.NewClient(nil)
processDto := lybic.SandboxProcessRequestDto{
Executable: "systemctl",
Args: []string{"--user", "is-active", "my-training-task"},
}
result, _ := client.ExecSandboxProcess(ctx, "SBX-xxxx", processDto)
stdout, _ := base64.StdEncoding.DecodeString(result.StdoutBase64)
status := strings.TrimSpace(string(stdout))
if status == "active" {
fmt.Println("✓ Task is running")
} else if status == "inactive" {
fmt.Println("✗ Task has stopped")
} else {
fmt.Printf("Task status: %s\n", status)
}
}Return values:
active: Task is runninginactive: Task has stoppedfailed: Task failed
Complete Example: Running a Web Server
Below is a complete example showing how to run a long-running Python web server in a sandbox:
import asyncio
import base64
from lybic import LybicClient, LybicAuth
async def run_web_server():
async with LybicClient(
LybicAuth(
org_id="ORG-xxxx",
api_key="lysk-xxxxxxxxxxx",
endpoint="https://api.lybic.cn/"
)
) as client:
sandbox_id = "SBX-xxxx"
# 1. Create web server script
server_code = """#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = {'status': 'ok', 'message': 'Hello from Lybic!'}
self.wfile.write(json.dumps(response).encode())
def log_message(self, format, *args):
print(f"{self.address_string()} - {format % args}")
if __name__ == '__main__':
server = HTTPServer(('0.0.0.0', 8080), Handler)
print("Server started at http://0.0.0.0:8080")
server.serve_forever()
"""
stdin_data = base64.b64encode(server_code.encode()).decode()
result = await client.sandbox.execute_process(
sandbox_id,
executable="bash",
args=["-c", "mkdir -p /home/agent/server && cat > /home/agent/server/app.py && chmod +x /home/agent/server/app.py"],
stdinBase64=stdin_data
)
if result.exitCode != 0:
print("Failed to create server script")
return
print("✓ Server script created successfully")
# 2. Start server with systemd
result = await client.sandbox.execute_process(
sandbox_id,
executable="systemd-run",
args=[
"--user",
"--unit=web-server",
"--description=Python Web Server",
"python3",
"/home/agent/server/app.py"
]
)
output = base64.b64decode(result.stdoutBase64 or '').decode()
print(f"✓ Web server started: {output}")
# 3. Wait a few seconds for server to start
await asyncio.sleep(3)
# 4. Check server status
result = await client.sandbox.execute_process(
sandbox_id,
executable="systemctl",
args=["--user", "is-active", "web-server"]
)
status = base64.b64decode(result.stdoutBase64 or '').decode().strip()
print(f"✓ Server status: {status}")
# 5. View logs
result = await client.sandbox.execute_process(
sandbox_id,
executable="journalctl",
args=["--user", "--unit=web-server", "-n", "10", "--no-pager"]
)
logs = base64.b64decode(result.stdoutBase64 or '').decode()
print("✓ Server logs:")
print(logs)
# 6. Test server
result = await client.sandbox.execute_process(
sandbox_id,
executable="curl",
args=["http://localhost:8080"]
)
response = base64.b64decode(result.stdoutBase64 or '').decode()
print(f"✓ Server response: {response}")
if __name__ == "__main__":
asyncio.run(run_web_server())import { LybicClient } from '@lybic/core'
const lybic = new LybicClient({
baseUrl: 'https://api.lybic.cn',
orgId: 'ORG-xxxx',
apiKey: 'lysk-your-api-key-here',
})
async function runWebServer() {
const sandboxId = 'SBX-xxxx'
// 1. Create web server script
const serverCode = `#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = {'status': 'ok', 'message': 'Hello from Lybic!'}
self.wfile.write(json.dumps(response).encode())
def log_message(self, format, *args):
print(f"{self.address_string()} - {format % args}")
if __name__ == '__main__':
server = HTTPServer(('0.0.0.0', 8080), Handler)
print("Server started at http://0.0.0.0:8080")
server.serve_forever()
`
const stdinBase64 = btoa(serverCode)
let result = await lybic.execSandboxProcess(sandboxId, {
executable: 'bash',
args: ['-c', 'mkdir -p /home/agent/server && cat > /home/agent/server/app.py && chmod +x /home/agent/server/app.py'],
stdinBase64: stdinBase64,
})
if (result.data?.exitCode !== 0) {
console.log('Failed to create server script')
return
}
console.log('✓ Server script created successfully')
// 2. Start server with systemd
result = await lybic.execSandboxProcess(sandboxId, {
executable: 'systemd-run',
args: [
'--user',
'--unit=web-server',
'--description=Python Web Server',
'python3',
'/home/agent/server/app.py',
],
})
const output = atob(result.data?.stdoutBase64 || '')
console.log('✓ Web server started:', output)
// 3. Wait a few seconds for server to start
await new Promise(resolve => setTimeout(resolve, 3000))
// 4. Check server status
result = await lybic.execSandboxProcess(sandboxId, {
executable: 'systemctl',
args: ['--user', 'is-active', 'web-server'],
})
const status = atob(result.data?.stdoutBase64 || '').trim()
console.log('✓ Server status:', status)
// 5. View logs
result = await lybic.execSandboxProcess(sandboxId, {
executable: 'journalctl',
args: ['--user', '--unit=web-server', '-n', '10', '--no-pager'],
})
const logs = atob(result.data?.stdoutBase64 || '')
console.log('✓ Server logs:')
console.log(logs)
// 6. Test server
result = await lybic.execSandboxProcess(sandboxId, {
executable: 'curl',
args: ['http://localhost:8080'],
})
const response = atob(result.data?.stdoutBase64 || '')
console.log('✓ Server response:', response)
}
runWebServer()Advanced Usage
Set Resource Limits
You can set CPU and memory limits for tasks:
systemd-run --user \
--unit=resource-limited-task \
--property=CPUQuota=50% \
--property=MemoryMax=512M \
python3 /home/agent/scripts/train.pySet Environment Variables
systemd-run --user \
--unit=task-with-env \
--setenv=API_KEY=your-key \
--setenv=DEBUG=true \
python3 /home/agent/scripts/app.pySet Working Directory
systemd-run --user \
--unit=task-with-workdir \
--working-directory=/home/agent/project \
python3 train.pyStop Task
To stop a running task:
systemctl --user stop my-training-taskList All User Tasks
systemctl --user list-units --type=serviceBest Practices
- Use meaningful unit names: Use descriptive
--unitnames for easier management - Add task descriptions: Use the
--descriptionparameter to add task documentation - Check logs regularly: Use
journalctlto monitor task output and catch issues early - Set resource limits: Set reasonable resource limits for long-running tasks to avoid affecting other tasks
- Add error handling: Include error handling and logging in your scripts
- Clean up tasks: Stop unnecessary tasks when complete to free resources
FAQ
Q: How do I know when a task is complete?
Regularly use systemctl --user is-active to check task status. When it returns inactive, the task has completed.
Q: How can I see the exit code of a task?
Use systemctl --user show my-training-task to view detailed information, including the ExecMainStatus field.
Q: Will tasks continue running after the sandbox restarts?
Temporary units created with systemd-run will not automatically restart after a sandbox restart. For persistence, you need to create permanent systemd service files.
Q: Can I run multiple tasks simultaneously?
Yes, simply use different --unit names for each task.
Q: How can I get real-time logs?
Due to API timeout limits, using journalctl -f is not recommended. Instead, call the API periodically to fetch the latest logs.
Related Documentation
- Running Commands and Executing Code - Short-term command execution
- File Transfer - Upload scripts and download results
- Python SDK Usage Guide
- TypeScript SDK Usage Guide