Contents

Automatically Cleaning Up Stuck Citrix Workspace Processes on Linux

Citrix Workspace on Linux can sometimes leave session-related processes running after a session has ended. This usually happens after a crash, timeout, failed logout, or a session that closes visually but does not fully terminate in the background.

The result is frustrating: the Citrix window is gone, but the system still has leftover Citrix processes running. When that happens, starting a new session may fail until those old processes are manually closed.

Instead of opening a task manager every time this happens, we can automate the cleanup with a small watchdog script and a user-level systemd service.

The issue

A normal Citrix session usually has an active wfica process. This is the main ICA session process.

After the session ends, wfica should disappear. However, other Citrix Workspace processes can sometimes remain behind, for example:

1
2
3
/opt/Citrix/ICAClient/adapter
/opt/Citrix/ICAClient/icasessionmgr
/opt/Citrix/ICAClient/UtilDaemon

These leftover processes can prevent a fresh session from starting properly.

The cleanup logic is simple:

1
2
3
4
5
If wfica is running:
    Citrix has an active session, so do nothing.

If wfica is not running:
    Check for leftover Citrix session processes and terminate them.

This avoids killing an active Citrix session while still cleaning up stale processes after the session has ended.

Overview of the solution

The solution has two parts:

  1. A watchdog script that checks for an active wfica process.
  2. A systemd user service that keeps the watchdog running in the background.

The script checks every 30 seconds. If no active wfica process exists, it looks for leftover Citrix processes and terminates them.

Because this is a user-level service, it does not require a system-wide daemon or root-level service configuration.

Create the watchdog script

Create a directory for user scripts if you do not already have one:

1
mkdir -p ~/.local/bin

Create the script:

1
nano ~/.local/bin/citrix-cleanup-watchdog.sh

Add the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env bash

CHECK_INTERVAL=30

CITRIX_LEFTOVERS='ICAClient/(adapter|icasessionmgr|UtilDaemon)|ICAClient//UtilDaemon'

while true; do
    # If an active wfica session exists, do nothing
    if pgrep -u "$USER" -f '/opt/Citrix/ICAClient/wfica' >/dev/null; then
        sleep "$CHECK_INTERVAL"
        continue
    fi

    # No wfica session exists, clean up leftover Citrix processes
    leftover_pids=$(pgrep -u "$USER" -f "$CITRIX_LEFTOVERS")

    if [ -n "$leftover_pids" ]; then
        pgrep -a -u "$USER" -f "$CITRIX_LEFTOVERS"

        pkill -TERM -u "$USER" -f "$CITRIX_LEFTOVERS"
        sleep 3
        pkill -KILL -u "$USER" -f "$CITRIX_LEFTOVERS"
    fi

    sleep "$CHECK_INTERVAL"
done

Make the script executable:

1
chmod +x ~/.local/bin/citrix-cleanup-watchdog.sh

How the script works

The script first checks whether an active Citrix ICA session exists:

1
pgrep -u "$USER" -f '/opt/Citrix/ICAClient/wfica'

If this command finds wfica, the script assumes a Citrix session is active and does nothing.

If wfica is not found, the script checks for leftover Citrix Workspace session processes using this pattern:

1
ICAClient/(adapter|icasessionmgr|UtilDaemon)|ICAClient//UtilDaemon

If matching processes are found, the script first sends a normal terminate signal:

1
pkill -TERM -u "$USER" -f "$CITRIX_LEFTOVERS"

It then waits three seconds and force-kills anything still running:

1
pkill -KILL -u "$USER" -f "$CITRIX_LEFTOVERS"

This gives the processes a chance to close cleanly before using SIGKILL.

Create the systemd user service

Create the user systemd directory if it does not already exist:

1
mkdir -p ~/.config/systemd/user

Create the service file:

1
nano ~/.config/systemd/user/citrix-cleanup-watchdog.service

Add the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Unit]
Description=Citrix leftover process cleanup watchdog

[Service]
ExecStart=%h/.local/bin/citrix-cleanup-watchdog.sh
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

In this file, %h expands to the current user’s home directory. So this:

1
ExecStart=%h/.local/bin/citrix-cleanup-watchdog.sh

points to:

1
~/.local/bin/citrix-cleanup-watchdog.sh

Using %h makes the service file more portable because it does not hardcode a specific username.

Enable and start the service

Reload the user systemd configuration:

1
systemctl --user daemon-reload

Start the watchdog:

1
systemctl --user start citrix-cleanup-watchdog.service

Enable it so it starts automatically when you log in:

1
systemctl --user enable citrix-cleanup-watchdog.service

Check the service status:

1
systemctl --user status citrix-cleanup-watchdog.service

View the logs

To follow the watchdog logs, run:

1
journalctl --user -u citrix-cleanup-watchdog.service -f

This is useful when testing the setup. If the script detects leftover Citrix processes, it prints them before terminating them.

Resource usage

The watchdog is lightweight. Most of the time it is sleeping.

Every 30 seconds it wakes up, runs a few process checks, and then goes back to sleep. It does not monitor network traffic, scan the filesystem, or perform any heavy background work.

In practice, the resource usage should be minimal:

  • Almost no CPU usage
  • A few MB of memory
  • No network usage
  • Very small log output unless cleanup happens

For a problem that otherwise requires manual cleanup, this is a reasonable trade-off.

Final result

With this watchdog running, Citrix Workspace cleanup becomes automatic.

When an active Citrix session is running, the script leaves it alone. When the session ends and wfica disappears, the script checks for leftover Citrix session processes and removes them.

This makes it possible to start a new Citrix session without first opening a task manager and manually killing stale processes.