Charlie Nash
10/21/2025, 3:52 PMMarvin
10/21/2025, 3:52 PMNate
10/21/2025, 3:53 PMCharlie Nash
10/21/2025, 3:54 PMNate
10/21/2025, 3:54 PMprefect shell watch
» uvx prefect shell watch "curl <http://ip.me|ip.me>"
10:54:21.864 | INFO | Flow run 'magnificent-dinosaur' - Beginning flow run 'magnificent-dinosaur' for flow 'Shell Command'
10:54:21.869 | INFO | Flow run 'magnificent-dinosaur' - View at <http://127.0.0.1:4200/runs/flow-run/8c4d3976-e2fc-4948-8d69-6874c9dc6317>
10:54:22.259 | INFO | Flow run 'magnificent-dinosaur' - 73.50.144.240
10:54:22.355 | INFO | Flow run 'magnificent-dinosaur' - Finished in state Completed()Charlie Nash
10/21/2025, 3:57 PMMarvin
10/21/2025, 3:59 PMpip install prefect prefect-shell
- Example flow that runs a bash script and streams logs to the Prefect UI:
from prefect import flow
from prefect_shell.commands import shell_run_command
@flow(name="Run Bash Script")
def run_bash_script(script_path: str, *args):
cmd = f"bash {script_path} {' '.join(args)}".strip()
output = shell_run_command(
command=cmd,
env={"FOO": "bar"}, # optional
cwd="/path/to/working/dir", # optional
)
return output
if __name__ == "__main__":
run_bash_script("/path/to/script.sh", "arg1", "arg2")
- Docs: prefect-shell integration
Option B: Use Prefect’s built-in process utilities (async, fine-grained control)
from prefect import flow, get_run_logger
from prefect.utilities.processutils import run_process
@flow(name="Run Bash Script (processutils)")
async def run_bash_script(script_path: str, *args):
logger = get_run_logger()
cmd = ["bash", script_path, *args]
proc = await run_process(
cmd,
stream_output=True, # stream stdout/stderr to Prefect logs
env={"FOO": "bar"}, # optional
cwd="/path/to/working/dir", # optional
)
<http://logger.info|logger.info>(f"Process exited with code: {proc.returncode}")
return proc.returncode
if __name__ == "__main__":
import asyncio
asyncio.run(run_bash_script("/path/to/script.sh", "arg1"))
- API reference: processutils
Option C: No Python code — turn a shell command into a flow via CLI
- For a one-off observed run:
prefect shell watch "bash /path/to/script.sh arg1 arg2"
- To create and serve a deployment (optionally on a schedule):
prefect shell serve "bash /path/to/script.sh arg1" --name "Run Bash Script" --deployment-name "bash-script" --cron-schedule "0 12 * * *" --timezone "UTC"
- CLI reference: prefect shell CLI
Notes and tips
- Working directory and environment: use cwd= and env= as shown above.
- Streaming logs: prefect-shell and run_process(..., stream_output=True) will stream output to your flow’s logs in the Prefect UI.
- Script location: ensure your script is available wherever your flow/worker runs (container, VM, etc.) and is executable if you call it directly.
- Reusability: prefect-shell also includes a ShellOperation block for storing command configs you can reuse across flows.
Would you like to:
- Run an existing script file (path/args)?
- Schedule it or run on-demand?
- Pass specific environment variables or secrets?
- Run in Docker/Kubernetes or just locally?
Share a bit more about your setup and goals, and I’ll tailor the example and deployment steps.