diff --git a/systemd/cloud-config.service b/systemd/cloud-config.service

index 3fe62f9..61cc567 100644

--- a/systemd/cloud-config.service

+++ b/systemd/cloud-config.service

@@ -16,7 +16,7 @@ Type=oneshot

 # process has completed this stage. The output from the return socket is piped

 # into a shell so that the process can send a completion message (defaults to

 # "done", otherwise includes an error message) and an exit code to systemd.

-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/config.sock | sh'

+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/config.sock

 RemainAfterExit=yes

 TimeoutSec=0

 

diff --git a/systemd/cloud-final.service b/systemd/cloud-final.service

index e7e892a..d5a1f08 100644

--- a/systemd/cloud-final.service

+++ b/systemd/cloud-final.service

@@ -19,7 +19,7 @@ Type=oneshot

 # process has completed this stage. The output from the return socket is piped

 # into a shell so that the process can send a completion message (defaults to

 # "done", otherwise includes an error message) and an exit code to systemd.

-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/final.sock | sh'

+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/final.sock

 RemainAfterExit=yes

 TimeoutSec=0

 TasksMax=infinity

diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl

index 41002fa..b452c41 100644

--- a/systemd/cloud-init-local.service.tmpl

+++ b/systemd/cloud-init-local.service.tmpl

@@ -32,7 +32,7 @@ ExecStartPre=/sbin/restorecon /run/cloud-init

 # process has completed this stage. The output from the return socket is piped

 # into a shell so that the process can send a completion message (defaults to

 # "done", otherwise includes an error message) and an exit code to systemd.

-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/local.sock | sh'

+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/local.sock

 RemainAfterExit=yes

 TimeoutSec=0

 

diff --git a/systemd/cloud-init-network.service.tmpl b/systemd/cloud-init-network.service.tmpl

index 710eb8c..5adccd8 100644

--- a/systemd/cloud-init-network.service.tmpl

+++ b/systemd/cloud-init-network.service.tmpl

@@ -53,7 +53,7 @@ Type=oneshot

 # process has completed this stage. The output from the return socket is piped

 # into a shell so that the process can send a completion message (defaults to

 # "done", otherwise includes an error message) and an exit code to systemd.

-ExecStart=sh -c 'echo "start" | nc -U /run/cloud-init/share/network.sock | sh'

+ExecStart=/usr/libexec/cloud-init/cloud-init-trigger /run/cloud-init/share/network.sock

 RemainAfterExit=yes

 TimeoutSec=0

 

diff --git a/tools/cloud-init-trigger b/tools/cloud-init-trigger

new file mode 100644

index 0000000..98984f9

--- /dev/null

+++ b/tools/cloud-init-trigger

@@ -0,0 +1,33 @@

+#!/usr/bin/env python

+import socket

+import sys

+import subprocess

+

+def main():

+    if len(sys.argv) < 2:

+        print("Usage: cloud-init-trigger <socket_path>")

+        sys.exit(0)

+

+    socket_path = sys.argv[1]

+    

+    try:

+        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:

+            client.connect(socket_path)

+            client.sendall(b'start')

+            message = client.recv(4096)

+            

+            if message:

+                cmd = message.decode().strip()

+                result = subprocess.run(cmd, shell=True)

+                sys.exit(result.returncode)

+            else:

+                print("Error: Received empty message from cloud-init-main")

+                sys.exit(0)

+                

+    except Exception as e:

+        print(f"Trigger error: {e}")

+        sys.exit(0)

+

+if __name__ == "__main__":

+    main()

+